公共字段自动填充、菜品管理

news2024/11/18 13:46:17

一、公共字段填充

1.1、问题分析

1.2、实现思路

1.3、代码开发

1.3.1、自定义注解

import com.sky.enumeration.OperationType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target ( ElementType.METHOD )
@Retention ( RetentionPolicy.RUNTIME )
public @interface AutoFill {
    //通过枚举类型指定数据库操作的类型
    //UPDATE INSERT
    OperationType value();
}

1.3.2、切面类

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 自定义切面,实现公共公共部分自动填充的逻辑
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    /**
     * 切入点 :对那些类的哪些方法进行拦截
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)") //切点表达式
    public void autoFillPointCut(){}
    /**
     * 前置通知,在通知中进行公共字段的赋值
     */
    @Before ( "autoFillPointCut()" )
    public void autoFill(JoinPoint joinPoint){
        log.info ( "开始进行公共字段自动填充" );

        //获取当前被拦截的方法上的数据库操作类型(获得签名)
        MethodSignature signature = (MethodSignature) joinPoint.getSignature ();//获得方法签名
        AutoFill autoFill = signature.getMethod ().getAnnotation ( AutoFill.class );//获得方法上的注解对象
        OperationType operationType = autoFill.value ();//获得数据库操作类型
        //获取到当前被拦截的参数--实体对象
        Object[] args = joinPoint.getArgs ();
        if (args==null || args.length==0){
            return;
        }
        Object entity = args[0];
        //准备赋值的数据
        LocalDateTime now = LocalDateTime.now ();
        Long currentId = BaseContext.getCurrentId ();

        //根据当前不同的操作类型,为对应的属性通过反射赋值
        if (operationType==OperationType.INSERT ){
            //为四个公共字段赋值
            try {
                //通过反射获得方法
                Method setCreatTime = entity.getClass ().getDeclaredMethod ( AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class );
                Method setCreateUser = entity.getClass ().getDeclaredMethod (AutoFillConstant.SET_CREATE_USER , Long.class );
                Method setUpdateTime = entity.getClass ().getDeclaredMethod ( AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class );
                Method setUpdateUser = entity.getClass ().getDeclaredMethod ( AutoFillConstant.SET_UPDATE_USER, Long.class );
                //通过反射进行赋值
                setCreatTime.invoke ( entity,now );
                setCreateUser.invoke ( entity,currentId );
                setUpdateTime.invoke ( entity,now );
                setUpdateUser.invoke ( entity,currentId );
            } catch (Exception e) {
                e.printStackTrace ();
            }
        }else if (operationType==OperationType.UPDATE){
            try {
                Method setUpdateTime = entity.getClass ().getDeclaredMethod ( AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class );
                Method setUpdateUser = entity.getClass ().getDeclaredMethod ( AutoFillConstant.SET_UPDATE_USER, Long.class );
                setUpdateTime.invoke ( entity,now );
                setUpdateUser.invoke ( entity,currentId );
            } catch (Exception e) {
                e.printStackTrace ();
            }
            //为两个公共字段赋值
        }
    }

}

二、新增菜品

2.1、需求分析和设计

2.2、文件上传

1.Controller层

import com.sky.result.Result;
import com.sky.utils.AliOssUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.UUID;

/**
 * 通用接口
 */
@RestController
@RequestMapping("/admin/common")
@Slf4j
@Api(tags = "通用接口")
public class CommonController {
    @Autowired
    private AliOssUtil aliOssUtil;
    /**
     * 文件上传
     * @param file
     * @return
     */
    @PostMapping("/upload")
@ApiOperation ( "文件上传" )
 public Result<String> upload(MultipartFile file){
    log.info ( "文件上传,{}",file );
        try {
            String originalFilename = file.getOriginalFilename ();//获得文件原来的文件名称
            //截取原始文件名的后缀
            String extension = originalFilename.substring ( originalFilename.lastIndexOf ( "." ) );
            //创建新的文件名称
            String objectName = UUID.randomUUID ().toString () + extension;
            String filePath = aliOssUtil.upload ( file.getBytes (), objectName );
            return Result.success (filePath);
        } catch (IOException e) {
            log.error ( "文件上传失败,{}",e );
        }
        return Result.error ( "文件上传失败" );

 }



}

2.3、新增菜品

1.DishController

    /**
     * 新增菜品
     * @param dishDTO
     * @return
     */
    @PostMapping
    @ApiOperation ( "新增菜品" )
    public Result save(@RequestBody DishDTO dishDTO){
        log.info ( "新增菜品,{}",dishDTO );
        dishService.saveWithFlavor (dishDTO);
        return Result.success ();

    }

2.DishServiceImlp

    /**
     * 新增菜品和对应的口味
     * @param dishDTO
     */
    @Transactional     //注解方式的事务管理  操作多张表保证数据的原子性,一致性
    @Override
    public void saveWithFlavor(DishDTO dishDTO) {
        Dish dish = new Dish ();
        BeanUtils.copyProperties ( dishDTO,dish );
        //向菜品表插入一条数据
        dishMapper.insert(dish);
        //获取Insert语句生成的主键值
        Long dishId = dish.getId ();
        //向口味表插入n条数据
        List<DishFlavor> flavors = dishDTO.getFlavors ();
        if (flavors !=null && flavors.size () >0){
            flavors.forEach ( dishFlavor -> dishFlavor.setDishId ( dishId ));
            //向口味表插入n条数据
         dishFlavorMapper.insertBatch(flavors);

        }

3.Mapper


import com.sky.annotation.AutoFill;
import com.sky.dto.DishDTO;
import com.sky.entity.Dish;
import com.sky.enumeration.OperationType;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface DishMapper {

    /**
     * 根据分类id查询菜品数量
     * @param categoryId
     * @return
     */
    @Select("select count(id) from dish where category_id = #{categoryId}")
    Integer countByCategoryId(Long categoryId);

    /**
     * 修改菜品信息
     * @param dishDTO
     */
    void updateDish(DishDTO dishDTO);

    /**
     * 新增菜品
     * @param dish
     */
    @AutoFill ( OperationType.INSERT )
    void insert(Dish dish);
}
import com.sky.entity.DishFlavor;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface DishFlavorMapper {
    /**
     * 批量插入口味数据
     * @param flavors
     */
    void insertBatch(List<DishFlavor> flavors);
}

4.XML

    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into dish(id,name,category_id,price,image,description,status,create_time,update_time,create_user,update_user)
        values(#{id},#{name},#{categoryId},#{price},#{image},#{description},#{status},#{createTime},#{updateTime},#{createUser},#{updateUser})
    </insert>
    <insert id="insertBatch">
        insert into dish_flavor (dish_id,name,value) values
        <foreach collection="flavors" item="df" separator=",">
            (#{df.dishId},#{df.name},#{df.value})
        </foreach>

    </insert>

三、菜品分页查询

3.1、需求分析设计

3.2、代码实现

1.Controller

    /**
     * 菜品分页查询
     * @param dishPageQueryDTO
     * @return
     */
    @ApiOperation ( "菜品分页查询" )
    @GetMapping("/page")
    public  Result<PageResult> dishPageQuery(DishPageQueryDTO dishPageQueryDTO){
        log.info ( "分页查询,{}",dishPageQueryDTO );
    PageResult pageResult= dishService.dishPageQuery(dishPageQueryDTO);
        return Result.success (pageResult);

    }

2.Service

    /**
     * 菜品分页查询
     * @param dishPageQueryDTO
     * @return
     */
    @ApiOperation ( "菜品分页查询" )
    @GetMapping("/page")
    public  Result<PageResult> dishPageQuery(DishPageQueryDTO dishPageQueryDTO){
        log.info ( "分页查询,{}",dishPageQueryDTO );
    PageResult pageResult= dishService.dishPageQuery(dishPageQueryDTO);
        return Result.success (pageResult);

    }

3.Mapper

<!--分页查询-->
    <select id="dishPageQuery" resultType="com.sky.vo.DishVO">
        select d.* ,c.name as categoryName from dish d  left outer join category c on d.category_id = c.id
        <where>
            <if test="name !=null"> and d.name like concat('%',#{name},'%')</if>
            <if test="categoryId !=null">and d.category_id =#{categoryId}</if>
            <if test="status !=null"> and d.status=#{status}</if>
        </where>
        order by d.create_time desc
    </select>

四、删除菜品

4.1、需求分析与设计

4.2、代码实现

1.Controller层

    /**
     * 批量删除菜品
     * @param ids
     * @return
     */
    @DeleteMapping
    @ApiOperation ( "批量删除菜品" )
    public Result delete(@RequestParam List<Long> ids ){
        log.info ( "批量删除菜品,{}",ids );
        dishService.deleteBatch(ids);
        return Result.success ();

    }

2.Service层

 /**
     * 批量删除
     * @param ids
     */
    @Transactional
    @Override
    public void deleteBatch(List<Long> ids) {
        //判断当前菜品是否能够删除--是否存在起售中的菜品??
        for (Long id : ids) {
        Dish dish=dishMapper.getById(id);
        if (dish.getStatus ()== StatusConstant.ENABLE){
            //当前菜品起售中,不能删除
            throw new DeletionNotAllowedException ( MessageConstant.DISH_ON_SALE );
        }
        }

        //判断当前菜品是否能够删除--当前菜品是否被套餐关联
        List<Long> setmealIds = setmealDishMapper.GetSetmealIdsByDishIds ( ids );
        if (setmealIds !=null && setmealIds.size ()>0){
            //当前菜品被套餐关联不能删除
            throw new DeletionNotAllowedException ( MessageConstant.DISH_BE_RELATED_BY_SETMEAL );
        }

        //删除菜品表中的菜品数据
        for (Long id : ids) {
            dishMapper.deleteById(id);
            //删除菜品关联的口味数据
            dishFlavorMapper.deleteByDishId(id);
        }

        

    }

3.Mapper层

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.SetmealDishMapper">

<!--根据菜品ID查询套餐ID-->
    <select id="GetSetmealIdsByDishIds" resultType="java.lang.Long">
     select setmeal_id from setmeal_dish where dish_id in
    <foreach collection="dishIds" item="dishId" separator="," open="(" close=")">
        #{dishId}
    </foreach>

    </select>
</mapper>
import com.sky.entity.DishFlavor;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface DishFlavorMapper {
    /**
     * 批量插入口味数据
     * @param flavors
     */
    void insertBatch(List<DishFlavor> flavors);

    /**
     * 根据菜品id删除对应的口味数据
     * @param dishId
     */
    @Delete ( "delete from dish_flavor where dish_id=#{dishId}" )
    void deleteByDishId(Long dishId);
}

五、修改菜品

5.1、需求分析设计

5.2、根据ID查询菜品接口开发

       service层

    /**
     * 根据ID查询菜品信息及口味
     * @param id
     * @return
     */
    @Transactional
    @Override
    public DishVO getById(Long id) {
    Dish dish =dishMapper.getById ( id );
    List<DishFlavor> flavors = dishFlavorMapper.getFlavor(id);
        DishVO dishVO = new DishVO ();
        BeanUtils.copyProperties ( dish,dishVO );
        dishVO.setFlavors ( flavors );
        return dishVO;
    }

5.3、修改菜品接口开发

1.Controller层

    /**
     * 修改菜品信息
     * @param dishDTO
     * @return
     */
    @PutMapping
    @ApiOperation ( "修改菜品" )
    public Result updateDish(@RequestBody DishDTO dishDTO){
        log.info ( "修改菜品,{}",dishDTO );
        dishService.updateDish(dishDTO);
        return Result.success ();
    }

2.Service层

    /**
     * 修改菜品
     * @param dishDTO
     */
    @AutoFill ( value = OperationType.UPDATE)
    @Override
    public void updateDish(DishDTO dishDTO) {
        //修改菜品基本信息
        Dish dish = new Dish ();
        BeanUtils.copyProperties ( dishDTO,dish );
        dishMapper.updateDish(dish);
        //删除原有的口味数据
        dishFlavorMapper.deleteByDishId (dishDTO.getId () );
        //重新插入口味数据
        List<DishFlavor> flavors = dishDTO.getFlavors ();
        if (flavors !=null && flavors.size ()>0){
            flavors.forEach ( dishFlavor ->{
                dishFlavor.setDishId ( dishDTO.getId () );
            } );
            dishFlavorMapper.insertBatch ( flavors );
        }


    }

3.Mapper层

    <update id="updateDish">
    update dish
    <set>
        <if test="categoryId !=null">category_id=#{categoryId},</if>
        <if test="description !=null">description=#{description},</if>
        <if test="id !=null">id =#{id},</if>
        <if test="image !=null">image =#{image},</if>
        <if test="name !=null">name =#{name},</if>
        <if test="price !=null">price =#{price},</if>
        <if test="status !=null">status=#{status}</if>
    </set>
    where id=#{id}
    </update>
    <insert id="insertBatch">
        insert into dish_flavor (dish_id,name,value) values
        <foreach collection="flavors" item="df" separator=",">
            (#{df.dishId},#{df.name},#{df.value})
        </foreach>

    </insert>
    /**
     * 根据菜品id删除对应的口味数据
     * @param dishId
     */
    @Delete ( "delete from dish_flavor where dish_id=#{dishId}" )
    void deleteByDishId(Long dishId);

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

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

相关文章

88 每日温度

每日温度 理解为什么用栈&#xff1a;一种在连续数据里的局部关系&#xff0c;这道题体现在temp[0]只和第一个比它大的值下标有关题解1 逆波兰栈改进(单调栈) 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 a…

【代码随想录03】哈希总结

哈希算法总结&#xff0c;拿去吧&#xff01;留下个赞

1-1 暴力破解-枚举

枚举&#xff1a;枚举所有的情况&#xff0c;逐个判断是否是问题的解 判断题目是否可以使用枚举&#xff1a;估算算法复杂度 1秒计算机大约能处理107的数据量&#xff0c;即O(n)107&#xff0c;则O(n2)能处理的数据量就是根号107≈3162 复杂度对应的数据量是该算法能处理的最…

SpringBoot2.7.17整合redis7

需要的依赖库&#xff1a; <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</gro…

0基础学习PyFlink——个数滑动窗口(Sliding Count Windows)

大纲 滑动&#xff08;Sliding&#xff09;和滚动&#xff08;Tumbling&#xff09;的区别样例窗口为2&#xff0c;滑动距离为1窗口为3&#xff0c;滑动距离为1窗口为3&#xff0c;滑动距离为2窗口为3&#xff0c;滑动距离为3 完整代码参考资料 在 《0基础学习PyFlink——个数…

电源控制系统架构(PCSA)之电源控制框架

安全之安全(security)博客目录导读 PCSA的主要目的是描述SoC系统电源控制集成的标准方法。这种方法的一个关键组成部分是电源控制框架。下图显示了电源控制框架概念的高级说明。 电源控制框架是标准基础设施组件、接口和相关方法的集合&#xff0c;可用于构建SoC电源管理所需的…

【Java初阶练习题】-- 循环练习题

循环练习题 1. 根据年龄, 来打印出当前年龄的人是少年(低于18), 青年(19-28), 中年(29-55), 老年(56以上)2. 判定一个数字是否是素数3. 打印 1 - 100 之间所有的素数4. 输出 1000 - 2000 之间所有的闰年5. 输出乘法口诀表6. 求两个正整数的最大公约数7. 求出0&#xff5e;999之…

滚动条默认是隐藏的只有鼠标移上去才会显示

效果 在设置滚动条的类名中写 /* 滚动条样式 */.content-box::-webkit-scrollbar {width: 0px; /* 设置纵轴&#xff08;y轴&#xff09;轴滚动条 */height: 0px; /* 设置横轴&#xff08;x轴&#xff09;轴滚动条 */}/* 滚动条滑块&#xff08;里面小方块&#xff09; */.…

Bellman-ford 贝尔曼-福特算法

Bellman-ford算法可以解决负权图的单源最短路径问题 --- 它的优点是可以解决有负权边的单源最短路径问题&#xff0c;而且可以判断是否负权回路 它也有明显的缺点&#xff0c;它的时间复杂度O&#xff08;N*E&#xff09;&#xff08;N是点数 &#xff0c; E是边数&#xff09…

实现多平台兼容性:开发同城外卖小程序的技术策略

在移动互联网时代&#xff0c;外卖行业的快速崛起改变了人们点餐的方式。随着小程序的兴起&#xff0c;开发同城外卖小程序成为了许多企业的重要战略。然而&#xff0c;小程序的多平台兼容性成为了一项关键挑战。本文将探讨如何实现多平台兼容性&#xff0c;以开发高效且用户友…

LeetCode 2402.会议室III ----堆+模拟

5e5 的st与ed 容易看出来是用堆来写的一道题目&#xff0c;一开始我只用了一个堆&#xff0c;出现了问题 问题就是当我们当前这个会议有多个可以选择的会议室可以选择的时候不一定选择那个最先结束的会议室而是应该选择可以选择的那些里面编号最小的那一个&#xff0c;因此我们…

ConfigurationProperties之宽松绑定

前面我们讲了ConfigurationProperties 但这个东西只能匹配小写 我这样写就正常 但当我们将配置文件和属性类都改成大写时 配置文件一切正常 但ConfigurationProperties就开始报错了 这涉及到一个知识点 宽松绑定 也叫做 松散绑定 其实 ConfigurationProperties提供给我们了…

Python 数学函数和 math 模块指南

Python 提供了一组内置的数学函数&#xff0c;包括一个广泛的数学模块&#xff0c;可以让您对数字执行数学任务。 内置数学函数。min() 和 max() 函数可用于在可迭代对象中查找最低或最高值&#xff1a; 示例&#xff1a;查找可迭代对象中的最低或最高值&#xff1a; x min…

深入理解udp

1.再谈端口号 1.1复习 我们上一篇谈了很久的应用层的http&#xff0c;并在此前我们使用socket编程写了一个能相互通信的客户端与服务端&#xff0c;但是我们也只是粗略的理解了一下tcp和udp在编程过程中所形成的差异性&#xff0c;并没有实质去了解一下其详细内容&#xff0c;…

KNN模型

使用K-Nearest Neighbors (KNN)算法进行分类。首先加载一个数据集&#xff0c;然后进行预处理&#xff0c;选择最佳的K值&#xff0c;并训练一个KNN模型。 # encodingutf-8 import numpy as np datas np.loadtxt(datingTestSet2.txt) # 加载数据集&#xff0c;返回一个numpy数…

68 内网安全-域横向PTHPTKPTT哈希票据传递

目录 演示案例:域横向移动PTH传递-Mimikatz域横向移动PTK传递-Mimikatz域横向移动PTT传递-MS14068&kekeo&local国产Ladon内网杀器测试验收-信息收集,连接等 涉及资源: PTH(pass the hash) #利用lm或ntlm的值进行的渗透测试 PTT(pass the ticket) #利用的票据凭证TGT进行…

餐饮连锁品牌2023:端起“外卖碗”,吃上“下沉饭”

作者 | 陈小江 文 | 螳螂观察 “没想到&#xff0c;蜜雪(蜜雪冰城&#xff09;能到我们这乡镇来开&#xff0c;我觉得挺意外的。「柏记水饺」也算挺大一品牌&#xff0c;没想到也能来&#xff08;我们&#xff09;乡镇”。 谈起不断有连锁品牌进镇开店&#xff0c;黑龙江讷河…

算法笔记【3】-冒泡排序法

文章目录 一、原理二、代码实现三、算法特点 一、原理 冒泡排序是一种简单但有效的排序算法&#xff0c;它可以用于对数字进行升序排序。该算法通过多次比较相邻元素并交换位置来实现排序的目的。冒泡排序的基本思想是从第一个元素开始&#xff0c;依次比较相邻的两个元素&…

python 练习 在列表元素中合适的位置插入 输入值

目的&#xff1a; 有一列从小到大排好的数字元素列表&#xff0c; 现在想往其插入一个值&#xff0c;要求&#xff1a; 大于右边数字小于左边数字 列表元素&#xff1a; [1,4,6,13,16,19,28,40,100] # 方法&#xff1a; 往列表中添加一个数值&#xff0c;其目的方便元素位置往后…

ardupilot开发 --- 深度相机 篇

1. ZED 相机 1.1 规格 2. RealSense 需要机载计算机作为中介&#xff01;&#xff01;