苍穹外卖-day04:项目实战-套餐管理(新增套餐,分页查询套餐,删除套餐,修改套餐,起售停售套餐)业务类似于菜品模块

苍穹外卖-day04

课程内容

  • 新增套餐
  • 套餐分页查询
  • 删除套餐
  • 修改套餐
  • 起售停售套餐

要求:

  1. 根据产品原型进行需求分析,分析出业务规则
  2. 设计接口
  3. 梳理表之间的关系(分类表、菜品表、套餐表、口味表、套餐菜品关系表)
  4. 根据接口设计进行代码实现
  5. 分别通过swagger接口文档和前后端联调进行功能测试

1. 新增套餐

1.1 需求分析和设计

产品原型:

在这里插入图片描述

在这里插入图片描述

业务规则:

  • 套餐名称唯一
  • 套餐必须属于某个分类
  • 套餐必须包含菜品
  • 名称、分类、价格、图片为必填项
  • 添加菜品窗口需要根据分类类型来展示菜品
  • 新增的套餐默认为停售状态

接口设计(共涉及到4个接口):

  • 根据类型查询分类(已完成)
  • 根据分类id查询菜品
  • 图片上传(已完成)
  • 新增套餐

在这里插入图片描述

在这里插入图片描述

数据库设计:

setmeal表为套餐表,用于存储套餐的信息。具体表结构如下:

字段名数据类型说明备注
idbigint主键自增
namevarchar(32)套餐名称唯一
category_idbigint分类id逻辑外键
pricedecimal(10,2)套餐价格
imagevarchar(255)图片路径
descriptionvarchar(255)套餐描述
statusint售卖状态1起售 0停售
create_timedatetime创建时间
update_timedatetime最后修改时间
create_userbigint创建人id
update_userbigint最后修改人id

setmeal_dish表为套餐菜品关系表,用于存储套餐和菜品的关联关系。具体表结构如下:

字段名数据类型说明备注
idbigint主键自增
setmeal_idbigint套餐id逻辑外键
dish_idbigint菜品id逻辑外键
namevarchar(32)菜品名称冗余字段
pricedecimal(10,2)菜品单价冗余字段
copiesint菜品份数

1.2 代码实现

1.2.1 DishController(根据分类id查询菜品)

在这里插入图片描述

/**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
*/
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<Dish>> list(Long categoryId){
    List<Dish> list = dishService.list(categoryId);
    return Result.success(list);
}
1.2.2 DishService
/**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
*/
List<Dish> list(Long categoryId);
1.2.3 DishServiceImpl(请求参数封装的不同情况)
/**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
*/
public List<Dish> list(Long categoryId) {
    Dish dish = Dish.builder()
        .categoryId(categoryId)
        .status(StatusConstant.ENABLE)
        .build();
    return dishMapper.list(dish);
}
1.2.4 DishMapper
/**
     * 动态条件查询菜品
     * @param dish
     * @return
*/
List<Dish> list(Dish dish);
1.2.5 DishMapper.xml
<select id="list" resultType="Dish" parameterType="Dish">
    select * from dish
    <where>
        <if test="name != null">
            and name like concat('%',#{name},'%')
        </if>
        <if test="categoryId != null">
            and category_id = #{categoryId}
        </if>
        <if test="status != null">
            and status = #{status}
        </if>
    </where>
    order by create_time desc
</select>

前后端联调:

在这里插入图片描述

在这里插入图片描述

1.2.6 SetmealController(新增套餐)

在这里插入图片描述

/**
 * 套餐管理
 */
@RestController
@RequestMapping("/admin/setmeal")
@Api(tags = "套餐相关接口")
@Slf4j
public class SetmealController {

    @Autowired
    private SetmealService setmealService;

    /**
     * 新增套餐
     * @param setmealDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增套餐")
    public Result save(@RequestBody SetmealDTO setmealDTO) {
        setmealService.saveWithDish(setmealDTO);
        return Result.success();
    }
}
1.2.7 SetmealService
public interface SetmealService {

    /**
     * 新增套餐,同时需要保存套餐和菜品的关联关系
     * @param setmealDTO
     */
    void saveWithDish(SetmealDTO setmealDTO);
}
1.2.8 SetmealServiceImpl(新增业务逻辑 类似新增菜品逻辑)
/**
 * 套餐业务实现
 */
@Service
@Slf4j
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;
    @Autowired
    private DishMapper dishMapper;

    /**
     * 新增套餐,同时需要保存套餐和菜品的关联关系
     * @param setmealDTO
     */
    @Transactional
    @Override
    public void saveWithDish(SetmealDTO setmealDTO) {
        //请求参数用的是SetmealDTO类封装的,包含套餐数据以及套餐菜品关系表数据,
        //   这个地方只需要插入套餐的基本信息,所以进行属性拷贝。
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);

        //向套餐表插入数据
        setmealMapper.insert(setmeal);

        //获取生成的套餐id   通过sql中的useGeneratedKeys="true" keyProperty="id"获取插入后生成的主键值
        //套餐菜品关系表的setmealId页面不能传递,它是向套餐表插入数据之后生成的主键值,也就是套餐菜品关系表的逻辑外键setmealId
        Long setmealId = setmeal.getId();

        //获取页面传来的套餐和菜品关系表数据
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        //遍历关系表数据,为关系表中的每一条数据(每一个对象)的setmealId赋值,
        //   这个地方不需要像之前写新增菜品时多写个if判断,因为之前的口味数据是非必须的,
        //   这个地方要求套餐必须包含菜品是必须的,所以不需要if判断,不存在套餐不包含菜品得情况
        setmealDishes.forEach(setmealDish -> {
            //将Setmeal套餐类的id属性赋值给SetmealDish套餐关系类的setmealId
            //套餐表的id保存在套餐关系表充当外键为setmealId
            setmealDish.setSetmealId(setmealId);
        });

        //保存套餐和菜品的关联关系  动态sql批量插入
        setmealDishMapper.insertBatch(setmealDishes);
    }
}
1.2.9 SetmealMapper
/**
     * 新增套餐
     * @param setmeal
*/
@AutoFill(OperationType.INSERT)
void insert(Setmeal setmeal);
1.2.10 SetmealMapper.xml
<insert id="insert" parameterType="Setmeal" useGeneratedKeys="true" keyProperty="id">
    insert into setmeal
    (category_id, name, price, status, description, image, create_time, update_time, create_user, update_user)
    values (#{categoryId}, #{name}, #{price}, #{status}, #{description}, #{image}, #{createTime}, #{updateTime},
    #{createUser}, #{updateUser})
</insert>
1.2.11 SetmealDishMapper
/**
     * 批量保存套餐和菜品的关联关系
     * @param setmealDishes
*/
void insertBatch(List<SetmealDish> setmealDishes);
1.2.12 SetmealDishMapper.xml
<insert id="insertBatch" parameterType="list">
    insert into setmeal_dish
    (setmeal_id,dish_id,name,price,copies)
    values
    <foreach collection="setmealDishes" item="sd" separator=",">
        (#{sd.setmealId},#{sd.dishId},#{sd.name},#{sd.price},#{sd.copies})
    </foreach>
</insert>

1.3 功能测试

略,还没有写分页查询,所以暂时不进行前后端联调。

2. 套餐分页查询(字段和属性不一致问题)

2.1 需求分析和设计

产品原型:

在这里插入图片描述

业务规则:

  • 根据页码进行分页展示
  • 每页展示10条数据
  • 可以根据需要,按照套餐名称、分类、售卖状态进行查询

接口设计:

在这里插入图片描述

2.2 代码实现

2.2.1 SetmealController

在这里插入图片描述

/**
     * 分页查询
     * @param setmealPageQueryDTO
     * @return
*/
@GetMapping("/page")
@ApiOperation("分页查询")
public Result<PageResult> page(SetmealPageQueryDTO setmealPageQueryDTO) {
    PageResult pageResult = setmealService.pageQuery(setmealPageQueryDTO);
    return Result.success(pageResult);
}
2.2.2 SetmealService
/**
     * 分页查询
     * @param setmealPageQueryDTO
     * @return
*/
PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
2.2.3 SetmealServiceImpl
    /**
     * 分页查询
     * @param setmealPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
        int pageNum = setmealPageQueryDTO.getPage();
        int pageSize = setmealPageQueryDTO.getPageSize();

        //需要在查询功能之前开启分页功能:当前页的页码   每页显示的条数
        PageHelper.startPage(pageNum, pageSize);
        //这个方法有返回值为Page对象,里面保存的是分页之后的相关数据
        Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);
        //封装到PageResult中:总记录数  当前页数据集合
        return new PageResult(page.getTotal(), page.getResult());
    }
2.2.4 SetmealMapper
/**
     * 分页查询
     * @param setmealPageQueryDTO
     * @return
*/
Page<SetmealVO> pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
2.2.5 SetmealMapper.xml
  • 问题:类似于菜品分页查询,在套餐分页查询中,套餐表setmeal保存的字段是category_id分类id,而接口文档要求返回的数据是分类名称。

  • 解决:使用左外连接查询。查询套餐表以及套餐对应的分类名称。

  • 注意:此时查询出套餐表中的字段 套餐名称为name,分类表中的字段分类名称也是name,那这样的话我们在封装数据的时候就会出现问题,通过mybatis框架去封装数据的时候由于这2个字段名相同,封装VO这个数据的时候就会对应错,分类表中的字段分类名称是name字段,SetmealVO是categoryName属性,字段名和属性名不一致所以封装不了数据。------------通过起字段别名方式解决c.name as categoryName

  • 名称习惯使用模糊查询而不是等号。

<select id="pageQuery" resultType="com.sky.vo.SetmealVO">
    select
    	s.*,c.name categoryName
    from
    	setmeal s
    left join
    	category c
    on
    	s.category_id = c.id
    <where>
        <if test="name != null">
            and s.name like concat('%',#{name},'%')
        </if>
        <if test="status != null">
            and s.status = #{status}
        </if>
        <if test="categoryId != null">
            and s.category_id = #{categoryId}
        </if>
    </where>
    order by s.create_time desc
</select>

2.3 功能测试

测试:分页查询
在这里插入图片描述

测试:新增套餐

在这里插入图片描述
在这里插入图片描述

3. 删除套餐(删除的业务逻辑)

3.1 需求分析和设计

产品原型:

在这里插入图片描述

业务规则:

  • 可以一次删除一个套餐,也可以批量删除套餐
  • 起售中的套餐不能删除

接口设计:

在这里插入图片描述

3.2 代码实现

3.2.1 SetmealController

在这里插入图片描述

/**
     * 批量删除套餐
     * @param ids
     * @return
*/
@DeleteMapping
@ApiOperation("批量删除套餐")
public Result delete(@RequestParam List<Long> ids){
    setmealService.deleteBatch(ids);
    return Result.success();
}
3.2.2 SetmealService
/**
     * 批量删除套餐
     * @param ids
*/
void deleteBatch(List<Long> ids);
3.2.3 SetmealServiceImpl
    /**
     * 批量删除套餐
     * @param ids
     */
    @Transactional
    @Override
    public void deleteBatch(List<Long> ids) {
        //判断当前套餐是否能够删除---是否存在起售中的套餐??
        //思路:遍历获取传入的id,根据id查询套餐setmeal中的status字段,0 停售 1 起售,
        //    如果是1代表是起售状态不能删除
        ids.forEach(id -> {
            Setmeal setmeal = setmealMapper.getById(id);
            if(StatusConstant.ENABLE == setmeal.getStatus()){
                //起售中的套餐不能删除
                throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
            }
        });


        //思路:套餐表和菜品表是多对多关系,把整个套餐都删除了,那么关系表中保存的套餐对应
        //     的菜品关系就没有意义了,所以此时也应该删除关系表中的数据。
        ids.forEach(setmealId -> {
            //删除套餐表中的数据
            setmealMapper.deleteById(setmealId);
            //删除套餐菜品关系表中的数据
            setmealDishMapper.deleteBySetmealId(setmealId);
        });
    }

类似于删除菜品,删除套餐的sql存在缺点:

  • 上述代码每一次for循环遍历都会发生2条sql(删除套餐、删除套餐菜品关系表数据),如果遍历的次数比较多,那么发出的sql数量也很多,可能会引发性能一些方面的问题。
  • 解决:减少sql语句的数量,使用动态sql批量删除,只需要1条sql就可以把需要删除的菜品删除掉,同样1条sql删除口味表的数据
  • 这里不在演示,详情查看day03-删除菜品。这里使用的是有缺点的方式做的删除。
3.2.4 SetmealMapper
/**
     * 根据id查询套餐
     * @param id
     * @return
*/
@Select("select * from setmeal where id = #{id}")
Setmeal getById(Long id);

/**
     * 根据id删除套餐
     * @param setmealId
*/
@Delete("delete from setmeal where id = #{id}")
void deleteById(Long setmealId);
3.2.5 SetmealDishMapper
/**
     * 根据套餐id删除套餐和菜品的关联关系
     * @param setmealId
*/
@Delete("delete from setmeal_dish where setmeal_id = #{setmealId}")
void deleteBySetmealId(Long setmealId);

3.3 功能测试

在这里插入图片描述

在这里插入图片描述

4. 修改套餐(修改的业务逻辑)

4.1 需求分析和设计

产品原型:

在这里插入图片描述

接口设计(共涉及到5个接口):

  • 根据id查询套餐
  • 根据类型查询分类(已完成)
  • 根据分类id查询菜品(已完成)
  • 图片上传(已完成)
  • 修改套餐

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.2 代码实现

4.2.1 SetmealController

在这里插入图片描述

/**
     * 根据id查询套餐,用于修改页面回显数据
     *
     * @param id
     * @return
*/
@GetMapping("/{id}")
@ApiOperation("根据id查询套餐")
public Result<SetmealVO> getById(@PathVariable Long id) {
    SetmealVO setmealVO = setmealService.getByIdWithDish(id);
    return Result.success(setmealVO);
}

/**
     * 修改套餐
     *
     * @param setmealDTO
     * @return
*/
@PutMapping
@ApiOperation("修改套餐")
public Result update(@RequestBody SetmealDTO setmealDTO) {
    setmealService.update(setmealDTO);
    return Result.success();
}
4.2.2 SetmealService
    /**
     * 根据id查询套餐和关联的菜品数据
     * @param id
     * @return
     */
    SetmealVO getByIdWithDish(Long id);

    /**
     * 修改套餐
     * @param setmealDTO
     */
    void update(SetmealDTO setmealDTO);
4.2.3 SetmealServiceImpl
    /**
     * 根据id查询套餐和套餐菜品关系
     *
     * @param id
     * @return
     */
    @Override
    public SetmealVO getByIdWithDish(Long id) {
        //根据id查询套餐表数据
        Setmeal setmeal = setmealMapper.getById(id);//删除菜品时写过了
        //根据id查询餐菜品关系表数据
        List<SetmealDish> setmealDishes = setmealDishMapper.getBySetmealId(id);

        //封装返回结果
        SetmealVO setmealVO = new SetmealVO();
        BeanUtils.copyProperties(setmeal, setmealVO);
        setmealVO.setSetmealDishes(setmealDishes);

        return setmealVO;
    }


    /**
     * 修改套餐
     *
     * 思路分析:套餐表修改直接使用update语句即可,对于这个套餐菜品关系表,
     *         套餐和菜品关系的修改比较复杂,因为它的情况有很多 有可能关系没有修改 有可能
     *         关系是追加的 也有可能关系是删除了,那么这个地方我们有没有一种比较
     *         简单的处理方式呢???
     *         可以先把你当前这个套餐菜品关系数据全都统一删掉,然后在按照你当前
     *         传过来的这个套餐菜品关系,重新再来插入一遍这个数据就可以了。
     *
     * @param setmealDTO
     */
    @Transactional
    public void update(SetmealDTO setmealDTO) {
        //说明:SetmealDTO含有套餐菜品关系表数据,当前只是修改套餐的基本信息,所以直接传递SetmealDTO不合适,
        //     可以把SetmealDTO的数据拷贝到套餐的基本信息类Setmeal中更合适。
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);

        //1、修改套餐表,执行update
        setmealMapper.update(setmeal);

        //获取生成的套餐id   通过sql中的useGeneratedKeys="true" keyProperty="id"获取插入后生成的主键值
        //套餐菜品关系表的setmealId页面不能传递,它是向套餐表插入数据之后生成的主键值,也就是套餐菜品关系表的逻辑外键setmealId
        Long setmealId = setmealDTO.getId();//新增套餐时的sql获取主键值

        //2、删除套餐和菜品的关联关系,操作setmeal_dish表,执行delete
        setmealDishMapper.deleteBySetmealId(setmealId); //删除套餐时已经实现了

        //获取页面传来的套餐和菜品关系表数据
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        //遍历关系表数据,为关系表中的每一条数据(每一个对象)的setmealId赋值,
        //   这个地方不需要像之前写新增菜品时多写个if判断,因为之前的口味数据是非必须的,
        //   这个地方要求套餐必须包含菜品是必须的,所以不需要if判断,不存在套餐不包含菜品得情况
        setmealDishes.forEach(setmealDish -> {
            setmealDish.setSetmealId(setmealId);
        });

        //3、重新插入套餐和菜品的关联关系,操作setmeal_dish表,执行insert
        //   动态sql批量插入
        setmealDishMapper.insertBatch(setmealDishes);//新增套餐时已经实现了
    }
4.2.4 SetmealMapper
    /**
     * 根据id查询套餐
     * @param id
     * @return
     */
    @Select("select * from setmeal where id = #{id}")
    Setmeal getById(Long id);


    //修改套餐表,执行update
    @AutoFill(OperationType.UPDATE)
    void update(Setmeal setmeal);
4.2.5 SetmealMapper.xml
    <update id="update">
        update setmeal
        <set>
            <if test="categoryId != null">category_id = #{categoryId},</if>
            <if test="name != null">name = #{name},</if>
            <if test="price != null">price = #{price},</if>
            <if test="status != null">status = #{status},</if>
            <if test="description != null">description = #{description},</if>
            <if test="image != null">image = #{image},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="updateUser != null">update_user = #{updateUser},</if>
        </set>
        where id = #{id}
    </update>
4.2.6 SetmealDishMapper
    /**
     * 根据套餐id查询套餐和菜品的关联关系
     * @param setmealId
     * @return
     */
    @Select("select * from setmeal_dish where setmeal_id = #{setmealId}")
    List<SetmealDish> getBySetmealId(Long setmealId);


    /**
     * 根据套餐id删除套餐和菜品的关联关系
     * @param setmealId
     */
    @Delete("delete from setmeal_dish where setmeal_id = #{setmealId}")
    void deleteBySetmealId(Long setmealId);

    /**
     * 批量保存套餐和菜品的关联关系
     * @param setmealDishes
     */
    void insertBatch(List<SetmealDish> setmealDishes);
4.2.7 SetmealDishMapper
    <insert id="insertBatch" parameterType="list">
        insert into setmeal_dish
        (setmeal_id,dish_id,name,price,copies)
        values
        <foreach collection="setmealDishes" item="sd" separator=",">
            (#{sd.setmealId},#{sd.dishId},#{sd.name},#{sd.price},#{sd.copies})
        </foreach>
    </insert>

4.3 功能测试

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

5. 起售停售套餐(业务逻辑)

5.1 需求分析和设计

产品原型:

在这里插入图片描述

业务规则:

  • 可以对状态为起售的套餐进行停售操作,可以对状态为停售的套餐进行起售操作
  • 起售的套餐可以展示在用户端,停售的套餐不能展示在用户端
  • 起售套餐时,如果套餐内包含停售的菜品,则不能起售

接口设计:

在这里插入图片描述

5.2 代码实现

5.2.1 SetmealController

在这里插入图片描述

/**
     * 套餐起售停售
     * @param status
     * @param id
     * @return
*/
@PostMapping("/status/{status}")
@ApiOperation("套餐起售停售")
public Result startOrStop(@PathVariable Integer status, Long id) {
    setmealService.startOrStop(status, id);
    return Result.success();
}
5.2.2 SetmealService
/**
     * 套餐起售、停售
     * @param status
     * @param id
*/
void startOrStop(Integer status, Long id);
5.2.3 SetmealServiceImpl
    /**
     * 套餐起售、停售
     * @param status
     * @param id
     */
    @Override
    public void startOrStop(Integer status, Long id) {
        //起售套餐时,判断套餐内是否有停售菜品,有停售菜品提示"套餐内包含未启售菜品,无法启售"
        if(status.equals(StatusConstant.ENABLE)){  //1  启用
            //select a.* from dish a left join setmeal_dish b on a.id = b.dish_id where b.setmeal_id = ?
            //左外连接查询,根据套餐id查询菜品以及对应的菜品套餐关系数据,a.*所以返回所有菜品数据
            List<Dish> dishList = dishMapper.getBySetmealId(id);
            if(dishList != null && dishList.size() > 0){//判断套餐中是否包含的有菜品,有才走if判断
                dishList.forEach(dish -> {
                    //套餐中包含菜品,如果这个菜品的状态为禁用,则抛出异常
                    if(StatusConstant.DISABLE.equals(dish.getStatus())){
                        throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
                    }
                });
            }
        }


        //执行流程: 如果是起售套餐,套餐内有停售菜品,则抛出异常 不能起售
        //         如果是起售套餐,套餐内没有停售菜品,if执行完后跳出继续向下执行,执行更新
        //         如果是停售套餐,不走上面的if,直接进行更新状态。
        Setmeal setmeal = Setmeal.builder()
                .id(id)
                .status(status)
                .build();
        setmealMapper.update(setmeal);//修改套餐时写了通用的修改sql
    }
5.2.4 DishMapper
/**
     * 根据套餐id查询菜品
     * @param setmealId
     * @return
*/
@Select("select a.* from dish a left join setmeal_dish b on a.id = b.dish_id where b.setmeal_id = #{setmealId}")
List<Dish> getBySetmealId(Long setmealId);
5.2.5 SetmealMapper
    //修改套餐表,执行update
    @AutoFill(OperationType.UPDATE)
    void update(Setmeal setmeal);
5.2.6 SetmealMapper.xml
    <update id="update">
        update setmeal
        <set>
            <if test="categoryId != null">category_id = #{categoryId},</if>
            <if test="name != null">name = #{name},</if>
            <if test="price != null">price = #{price},</if>
            <if test="status != null">status = #{status},</if>
            <if test="description != null">description = #{description},</if>
            <if test="image != null">image = #{image},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="updateUser != null">update_user = #{updateUser},</if>
        </set>
        where id = #{id}
    </update>

5.3 功能测试

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

几个不错的 Jupyter Notebook 云端展示平台

jupyter nbviewer URL:https://nbviewer.jupyter.org/ 结合Github的示例用法&#xff1a;https://nbviewer.jupyter.org/github/ <用户名或者用户名/存放ipynb文件的仓库或者Gist ID> 例如&#xff1a;https://nbviewer.jupyter.org/github/yeshan333/JupyterNotebook…

通过点击按钮实现查看全屏和退出全屏的效果

动态效果如图&#xff1a; 可以通过点击按钮&#xff0c;或者esc键实现全屏和退出全屏的效果 实现代码&#xff1a; <template><div class"hello"><el-button click"fullScreen()" v-if"!isFullscreen">查看全屏</el-butt…

登录远程SQLServer

1&#xff0c;登录格式: 服务器名称:192.168.0.104,1433 192.168.0.104&#xff1a;SQLServer所在远程PC的IP &#xff0c;&#xff1a;逗号分割IP与端口号 1433&#xff1a;SQLServer所使用的端口号&#xff08;默认为1433&#xff09;&#xff0c;当使用默认端口号时可以省…

《1w实盘and大盘基金预测 day6》

昨日预测完美&#xff0c;点位基本符合&#xff0c;我预测3052&#xff0c;实际最低3055。 走势也符合高平开&#xff0c;冲高回落&#xff0c;再反震荡上涨 大家可以观察我准不准哟&#xff5e;后面有我的一些写笔记、分享的网站。 关注公众号&#xff0c;了解各种理财预测内…

WanAndroid(鸿蒙版)开发的第三篇

前言 DevEco Studio版本&#xff1a;4.0.0.600 WanAndroid的API链接&#xff1a;玩Android 开放API-玩Android - wanandroid.com 其他篇文章参考&#xff1a; 1、WanAndroid(鸿蒙版)开发的第一篇 2、WanAndroid(鸿蒙版)开发的第二篇 3、WanAndroid(鸿蒙版)开发的第三篇 …

微信小程序 nodejs+vue+uninapp学生在线选课作业管理系统

基于微信小程序的班级作业管理助手使用的是MySQL数据库&#xff0c;nodejs语言和IDEA以及微信开发者工具作为开发工具&#xff0c;这些技术和工具我在日常的作业中都经常的使用&#xff0c;并且因为对编程感兴趣&#xff0c;在闲暇时间也进行的进行编程的提高&#xff0c;所以在…

09|代理(上):ReAct框架,推理与行动的协同

应用思维链推理并不能解决大模型的固有问题&#xff1a;无法主动更新自己的知识&#xff0c;导致出现事实幻觉。也就是说&#xff0c;因为缺乏和外部世界的接触&#xff0c;大模型只拥有训练时见过的知识&#xff0c;以及提示信息中作为上下文提供的附加知识。如果你问的问题超…

AI+权重衰退

AI权重衰退 1权重衰退2代码实现 2丢弃法 1权重衰退 AI权重衰退是指在人工智能&#xff08;AI&#xff09;领域中的一种技术或方法&#xff0c;用于训练机器学习模型时对权重进行惩罚或调整&#xff0c;以避免过拟合现象的发生。 在机器学习中&#xff0c;过拟合是指模型在训练…

c语言文件操作(中)

目录 1. 文件的顺序读写1.1 顺序读写函数1.2 顺序读写函数的原型和介绍 结语 1. 文件的顺序读写 1.1 顺序读写函数 函数名功能适用于fgetc字符输入函数所有输出流fputc字符输出函数所有输出流fgets文本行输入函数所有输出流fputs文本行输出函数所有输出流fscanf格式化输入函数…

苍穹外卖-day08:导入地址簿功能代码(单表crud)、用户下单(业务逻辑)、订单支付(业务逻辑,cpolar软件)

苍穹外卖-day08 课程内容 导入地址簿功能代码用户下单订单支付 功能实现&#xff1a;用户下单、订单支付 用户下单效果图&#xff1a; 订单支付效果图&#xff1a; 1. 导入地址簿功能代码&#xff08;单表crud&#xff09; 1.1 需求分析和设计 1.1.1 产品原型&#xff08…

C++_day6

思维导图&#xff1a; 2试编程 封装一个动物的基类&#xff0c;类中有私有成员: 姓名&#xff0c;颜色&#xff0c;指针成员年纪 再封装一个狗这样类&#xff0c;共有继承于动物类&#xff0c;自己拓展的私有成员有:指针成员:腿的个数(整型 int count)&#xff0c;共有成员函数…

7.测试教程-自动化测试selenium-2

文章目录 1.webdriver API1.1元素的定位1.2id定位1.3name 定位1.4tag name 定位和class name 定位1.5CSS 定位(常用)1.5.1概念1.5.2实操1.5.3语法 1.6XPath 定位1.6.1概念1.6.2实操1.6.3语法 1.7link text定位1.8Partial link text 定位1.9一个简单的测试实战1.10CSS定位和XPat…

【人工智能】英文学习材料03(每日一句)

&#x1f33b;个人主页&#xff1a;相洋同学 &#x1f947;学习在于行动、总结和坚持&#xff0c;共勉&#xff01; 目录 Chain Rule (链式法则) Dimensionality Reduction (降维) Long Short-Term Memory (LSTM) (长短期记忆网络) Gradient Explosion (梯度爆炸) Gradie…

Java项目:63 ssm网上花店设计+vue

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统具备友好性且功能完善。管理员登录进入后台之后&#xff0c;主要完成花材选择管理&#xff0c;用户管理&#xff0c;鲜花管理&#xff0c;鲜花出入…

计算机网络实践学习 思科实验31:配置思科DHCP

思科实验31&#xff1a;配置思科DHCP 实验拓扑图实验目标实验步骤实验配置 实验拓扑图 实验目标 配置思科设备作为DHCP服务器 实验步骤 配置OSPF路由协议配置R1为DHCP服务器配置DHCP中继&#xff0c;使得PC3可以获得地址全网通信测试 实验配置 1、配置R1为DHCP服务器&…

React Native: could not connect to development server

问题&#xff1a; 运行模拟器错误&#xff1a;无法连接到开发服务器 原因分析&#xff1a; 1、确认模拟器连接状态&#xff0c;是连接成功的 查看进程的端口占用&#xff0c;也没问题 lsof -i tcp:8081 kill pid2、检查包服务器是否运行正常 连接真机进行调试发现真机是正常…

【力扣精选算法100道】——带你了解(数组模拟栈)算法

目录 &#x1f4bb;比较含退格的字符串 &#x1f388;了解题意 &#x1f388;分析题意 &#x1f6a9;栈 &#x1f6a9;数组模拟栈 &#x1f388;实现代码 844. 比较含退格的字符串 - 力扣&#xff08;LeetCode&#xff09; &#x1f4bb;比较含退格的字符串 &#x1f3…

查看网卡和网关命令

ifconfig&#xff08;接口配置&#xff09; 是一个网络管理工具&#xff0c;它用于配置和查看 Linux 操作系统中网络接口的状态&#xff0c;使用ifconfig&#xff0c;您可以分配 IP 地址、启用或禁用接口、管理 ARP 缓存、路由等。 ping命令是个使用频率极高的网络诊断工具。…

win32汇编弹出对话框

之前书上有一个win32 asm 的odbc例子&#xff0c;它有一个窗体&#xff0c;可以执行sql&#xff1b;下面看一下弹出一个录入数据的对话框&#xff1b; 之前它在.code段包含2个单独的asm文件&#xff0c;增加第三个&#xff0c;增加的这个里面是弹出对话框的窗口过程&#xff0…

01初识Python

一、Python 简介 二、为什么要学Python&#xff1f; 三、Python 安装 四、输出第一条指令 五、总结 一、Python 简介 Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年创建。它具有简单易学的语法结构&#xff0c;被广泛应用于Web开发、数据科学、人工智…
最新文章