当前位置: 首页 > news >正文

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

一、公共字段填充

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 INSERTOperationType 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 {@Autowiredprivate 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     //注解方式的事务管理  操作多张表保证数据的原子性,一致性@Overridepublic 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@Overridepublic 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@Overridepublic 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)@Overridepublic 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);

相关文章:

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

一、公共字段填充 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 jav…...

前端面试 面试多起来了

就在昨天 10.17 号,同时收到了三个同学面试的消息。他们的基本情况都是双非院校本科、没有实习经历、不会消息中间件和 Spring Cloud 微服务,做的都是单体项目。但他们投递简历还算积极,从今年 9 月初就开始投递简历了,到现在也有一个多月了。 来看看,这些消息。 为…...

Qt常见类名关系整理

1、QAbstractItemModel与QAbstractItemView 模型的基类: The QAbstractItemModel class provides the abstract interface for item model classes. Inherited By: QAbstractListModel&#xff0c;QAbstractProxyModel,and QAbstractTableModel 视图的基类: The QAbstractIte…...

YOLO8实战:yolov8实现行人跟踪计数

本篇文章首先介绍YOLOV8实现人流量跟踪计数的原理,文末附代码 引言:行人跟踪统计是智能监控系统中的重要功能,可以广泛应用于人流控制、安全监控等领域。传统的行人跟踪算法往往受到光照、遮挡等因素的干扰,难以实现准确跟踪。随着深度学习技术的发展,目标检测模型逐渐成为…...

shell脚本学习-2

文章目录 一、shell参数传递二、shell中的特殊变量三、shell中的函数四、shell函数中的参数 一、shell参数传递 运行 Shell 脚本文件时我们可以给它传递一些参数&#xff0c;这些参数在脚本文件内部可以使用$n的形式来接收&#xff0c;例如&#xff0c;$1 表示第一个参数&…...

web3:智能合约浏览器版本的 IDE - remix 使用教程

如果你是一位web3行业的从业者,那么智能合约一定是要接触的,这里我们就智能合约浏览器版本的 IDE-remix来介绍一下,及简单的使用操作 目录 Remix简介官方网址语言设置使用编辑合约编译合约部署合约测试验证Remix简介 Remix 是一个开源的 Solidity 智能合约开发环境,是一款…...

信号类型(通信)——QPSK、OQPSK、IJF_OQPSK调制信号

系列文章目录 《信号类型&#xff08;通信&#xff09;——仿真》 《信号类型&#xff08;通信&#xff09;——QAM调制信号》 文章目录 前言 一、QPSK通信调制信号 1.1、原理 1.2、仿真 二、OQPSK通信调制信号 1.1、原理 1.2、仿真 三、IJF_OQPSK通信调制信号 1.1、…...

常用压缩文件操作函数总结

常用压缩文件操作函数总结 1- 解压gz文件 gzip -d xx.gz 2- 函数 1 打开文件 函数名&#xff1a; gzopen 功能描述&#xff1a; 打开名为file的gz文件 参数: file:文件名 mode:打开模式 r 返回值: 打开的gz文件描述符 gzFile gzopen(const char *file, const char…...

leetcode_274 H指数

1. 题意 在数组中找到最大的k, 使得至少k个数不小于k。 H指数 2. 题解 2.1 排序 从大到小排序完后&#xff0c;直接模拟即可。 class Solution { public:int hIndex(vector<int>& citations) {sort( citations.begin(), citations.end() );int res 0;int cur …...

微服务框架Consul--新手入门

Consul Consul 是由 HashiCorp 开发的一款软件工具&#xff0c;提供了一组功能&#xff0c;用于服务发现、配置管理和网络基础设施自动化。它旨在帮助组织管理现代分布式和微服务架构系统的复杂性。以下是Consul的一些关键方面和功能&#xff1a; 服务发现&#xff1a;Consul …...

docker运行syslog-ng,搭建日志服务器

Splunk 的数据很多是用syslog-ng 来收集的。 使用docker 来搭建syslog-ng 服务器还是很方便的。 #create network docker network create -d macvlan --subnet=192.7.0.0/16 --gateway=192.7.0.1 -o parent=ens35 docker-out docker network create -d macvlan --ipv6 --sub…...

Redis代替session实现用户验证

一、Redis代替session实现用户验证。 下图是session的实现登录需要实现的代码模块&#xff0c;虽然可以实现完整功能&#xff0c;但是仍然存在一些问题。 在以往使用session当作用户验证的过程中&#xff0c;会有session共享的问题&#xff0c;每次承担请求的tomcat是不一样…...

Ubuntu 内核降级到指定版本

reference https://www.cnblogs.com/leebri/p/16786685.html 前往此网站&#xff0c;找到所需的内核 https://kernel.ubuntu.com/~kernel-ppa/mainline/ 查看系统架构 dpkg --print-architecture 二、下载安装包 注意&#xff1a;下载除lowlatency以外的deb包 三、安装内核 3…...

uniapp开发app,在ios真机上出现的css样式问题

比如下面的问题&#xff0c;在iphone 13上出现&#xff0c;在iphone xR上正常。 问题一&#xff1a;border:1rpx造成边框显示不全 在iphone13上border边框有一部分不显示&#xff1a; 在iphone xR上显示正常&#xff1a; 解决办法是&#xff1a; 将border边框设置中的1rpx改…...

uniapp 页面间传参方法

页面之间传参大概可分为以下几种情况&#xff1a; 上级页面 → 下级页面&#xff08;单向&#xff09;上级页面 ← 下级页面&#xff08;单向&#xff09;上级页面 ↔ 下级页面&#xff08;双向&#xff09; 一、上级页面 → 下级页面&#xff08;单向&#xff09; uni.naviga…...

【年终特惠】基于最新导则下生态环评报告编制技术暨报告篇、制图篇、指数篇、综合应用篇系统性实践技能提升

根据生态环评内容庞杂、综合性强的特点&#xff0c;依据生态环评最新导则&#xff0c;将内容分为4大篇章(报告篇、制图篇、指数篇、综合篇)、10大专题(生态环评报告编制、土地利用图的制作、植被类型及植被覆盖度图的制作、物种适宜生境分布图的制作、生物多样性测定、生物量及…...

驱动开发7 基于GPIO子系统编写LED驱动,编写应用程序进行测试设置定时器,5秒钟打印一次hello world

驱动代码 #include <linux/init.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/gpio.h> #include <linux/timer.h> #include <linux/of_irq.h> #include <linux/interrupt.h…...

亚马逊云科技为奇点云打造全面、安全、可扩展的数据分析解决方案

刘莹奇点云联合创始人、COO&#xff1a;伴随云计算的发展&#xff0c;数据技术也在快速迭代&#xff0c;成为客户迈入DT时代、实现高质量发展的关键引擎。我们很高兴能和云计算领域的领跑者亚马逊云科技一同&#xff0c;不断为客户提供安全可靠的产品与专业的服务。 超过1500家…...

应用案例|基于三维机器视觉的曲轴自动化上下料应用方案

Part.1 项目背景 此案例服务对象为国内某知名大型汽车零部件制造工厂&#xff0c;该工厂有针对曲轴工件的自动化上下料需求。由于之前来料码放不规范&#xff0c;工件无序散乱摆放&#xff0c;上料节拍要求高&#xff0c;该工厂上下料效率极低。 Part.2 传统曲轴上下料存在的缺…...

关于ios和Android手机的下载pdf文件功能探讨

现象 在工作中遇到了一个需求,在app中需要对一些协议(pdf格式的)进行下载,实现方法创建a标签,设置href的值为下载地址,设置download属性,调用a标签的点击事件进行下载,在Android手机中是调起默认浏览器的下载功能(正常现象,可以实现功能),但是在ios手机中是直接进行文件的有预…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...