基于springboot+Vue的疫情防控系统(程序+数据库)

news2024/11/15 11:19:13

大家好✌!我是CZ淡陌。一名专注以理论为基础实战为主的技术博主,将再这里为大家分享优质的实战项目,本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路,向着优秀程序员前行!
🍅更多优质项目👇🏻👇🏻可点击下方获取🍅
文章底部或评论区获取🍅
Java项目精品实战案例《100套》

文章目录

  • 项目介绍
  • 一、选题背景意义
      • 1.项目背景
      • 2.研究意义
      • 3.技术栈
  • 二、运行效果
      • 1.登录注册
      • 2.首页
      • 3.住户管理
      • 4.注入出入登记
      • 5.访客模块
      • 6.用户管理信息
      • 7.其他模块
  • 三、部分代码实现
      • 1.用户信息判断
      • 2.登录拦截器
      • 3.基础的增删改查
    • 总结


📣 有源码 查看源码

项目介绍

针对疫情防控管理系统提出实现方案,按照软件开发的一般流程进行前期的调研和分析确定软件是否能够正常实现、技术是否可行和系统功能模块的设计开发,最后确定了使用的技术和实现系统的方案。

框架属于一种程序开发者实现的功能集合,可以帮助软件开发者快速构建软件层次架构和复用功能的一款工具,本平台框架使用了开源框架,具有比较好的开发优势,可以帮助软件开发者快速构建基本的程序开发框架出来,通过调用开源框架开源帮助程序开发者减少开发难度,提升了疫情防控管理系统的安全和稳定性。


一、选题背景意义

1.项目背景

互联网发展到现在已经有七十多年的时间了,随着信息技术的不断发展,互联网会涉及到人们生活的各个方面当中,互联网时代来临的时候可以推动各个行业的发展,给社会的经济领域添加了不少活力。

在当今的时候,很多行业都离不开互联网,尤其是在互联网时代下产生的疫情防控管理系统更是受到人们的欢迎。疫情防控管理系统的发展已有不少的时间,具有不同的种类。疫情防控管理系统跟疫情防控业务息息相关,不少用户想要定制特定的系统功能,因此市场具有广阔的前景。疫情防控管理系统如此火爆有以下原因[1]。

(1)相比于较传统的工作模式,疫情防控管理系统能够提高管理员管理的效率和降低出错的效率。疫情防控管理系统功能经过编译运行能够大大降低管理员管理出错的概率,管理员管理系统的时候如果发生了错误的情况系统会给出相应的提示。

(2)通过疫情防控管理系统管理能够降低成本,可以节省大量的时间成本和人力资源,管理员能够提高管控能力。

2.研究意义

随着现代科学技术的发展,互联网产品已经涉及到生活的很多方面,很多公司也在加快投入力度。然而在和防控工作人员沟通过程当中发现居民打卡的工作模式还处于人工管理的模式,这不能够充分地利用互联网技术提高工作效率。

建立规范化的流程能够管理居民健康打卡,而目前管理居民健康打卡只能依赖于管理员手工进行管理,科技发展能够为我们的生活提供服务,现在较多的场景都需要使用信息化管理。在我们的平时工作的时候,可以切实感受到科学技术带来的解决方式。在我们平时生活的时候也有较多的场景需要技术的辅助

3.技术栈

开发系统:Windows10
架构模式:MVC/前后端分离
JDK版本:Java JDK1.8
开发工具:IDEA
数据库版本: mysql8.0
数据库可视化工具: navicat
服务器:SpringBoot自带 apache tomcat
主要技术:Java,Springboot,mybatis,mysql,jquery,html,vue

二、运行效果

1.登录注册

在这里插入图片描述

2.首页

在这里插入图片描述

3.住户管理

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

4.注入出入登记

在这里插入图片描述

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

5.访客模块

在这里插入图片描述

6.用户管理信息

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

7.其他模块

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

在这里插入图片描述

三、部分代码实现

1.用户信息判断

@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {


    final UserMapper userMapper;

    final CodeMapper codeMapper;

    final UserRoleMapper userRoleMapper;




    public UserServiceImpl(UserRoleMapper userRoleMapper,
                           CodeMapper codeMapper,
                           UserMapper userMapper
                         ){
        this.userMapper=userMapper;
        this.codeMapper = codeMapper;
        this.userRoleMapper = userRoleMapper;

    }


        @Override
    public void reg(User user) throws Exception {
        //判断注册码信息
        Code code = codeMapper.selectBycodeText(user.getCodeText());
        User byAccount = userMapper.findByAccount(user.getAccount());
        if ( byAccount != null){
            throw new Exception("该账户名已被注册,请更换账户名字");
        }
        if(!RegularExpression.decideAccounNumber(user.getAccount())){
            throw new Exception("匹配帐号不合法合法(必须是字母开头,允许5-16字节,允许字母数字下划线)");
        }
        if(!RegularExpression.decideAccounNumberPassword(user.getPassword())){
            throw new Exception("匹配帐号密码不合法(必须5-16字节,允许字母数字下划线)");
        }
        if(!RegularExpression.decidePhone(user.getUserPhone())){
            throw new Exception("手机号码第一个数必须为1,[3,5,7,8]:手机号码第二个数必须为:括号内数字");
        }
        if(!RegularExpression.decideRealName(user.getUserName())){
            throw new Exception("匹配真实姓名不合法(只允许2-6汉字)");
        }
        if (code == null ){
            throw new Exception("注册码不能为空或者注册码信息错误,请联系管理员");
        }

        if (code.getStatus() == 0){
            //可以用
            //铭文密码 + 盐  + 散列
            Md5Hash md5Hash = new Md5Hash(user.getPassword(), user.getCodeText(),1024);
            user.setPassword(md5Hash.toHex());
            code.setStatus(1);
            userMapper.save(user);
            //添加角色和用户的关系
            userRoleMapper.add(user.getUserId(),code.getRoleId());
            //xuy
            codeMapper.updateByUser(user);

        }else if (code.getStatus() == 1){
            //不可用
            throw new Exception("注册码不可用或者已经被注册,请联系管理员");
        }



    }

    @Override
    public User findByAccount(String account)  {
        User user = userMapper.findByAccount(account);
        return user;
    }

    @Override
    public User findRolesByAccount(String account) {
        return userMapper.findRolesByAccount(account);
    }


    @Override
    public List<Menu> findMenuByRoleId(Integer roleId) {
        return userMapper.findMenuByRoleId(roleId);
    }



    @Override
    public User removeUpdateByUserid(Integer userId) {
        User user = userMapper.findByUserId(userId);
        if (user.getStatus() == ConstantsUtils.CODE_STATUS_0){
          user.setStatus(ConstantsUtils.CODE_STATUS_1);
        }
        else{
            user.setStatus(ConstantsUtils.CODE_STATUS_0);
        }
        userMapper.deleteUpdate(user);
        return user;
    }

    @Override
    public boolean deleteById(Integer id) throws Exception {
        //删除用户
        int i = userMapper.deleteById(id);
        if(i<0){
            throw  new Exception("删除失败");
        }
        //删除关系
        int a = userRoleMapper.deleteByuserId(id);
        if(a<0){
            throw  new Exception("删除失败");
        }

        return true;
    }

    @Override
    public List<User> queryAllUser(String account, String userName, String userPhone) {
        List<User> collect = this.userMapper.selectAll(account,userName,userPhone).stream()
                .filter(u -> account == null || account == "" || u.getAccount().equals(account))
                .filter(u -> userName == null || userName == "" || u.getUserName().equals(userName))
                .filter(u -> userPhone == null || userPhone == "" ||  u.getUserPhone().equals(userPhone))
                .collect(Collectors.toList());
        return collect;
    }

    @Override
    public int resetPassword(String account) {
        User byAccount = userMapper.findByAccount(account);
        //铭文密码 + 盐  + 散列
        Md5Hash md5Hash = new Md5Hash(ConstantsUtils.CODE_STATUS_666666, byAccount.getCodeText(),1024);
//        byAccount.setPassword(md5Hash.toHex());
//        String password = byAccount.getPassword();
        return userMapper.updatePasswordByAccount(account,md5Hash.toHex());
    }

    @Override
    public User findUserByAccount(String account) {
        return userMapper.findUserByAccount(account);
    }

    @Override
    public User editUser(User user) {
        userMapper.updateUser(user);
        return userMapper.findByAccount(user.getAccount());
    }

    @Override
    public User editPwd(User user) throws Exception {
        //判断密码格式
        if(!RegularExpression.decideAccounNumberPassword(user.getPassword())){
            throw new Exception("匹配帐号密码不合法(必须5-16字节,允许字母数字下划线)");
        }
        if(!RegularExpression.decideAccounNumberPassword(user.getNewPassword())){
            throw new Exception("匹配帐号密码不合法(必须5-16字节,允许字母数字下划线)");
        }
        if(!RegularExpression.decideAccounNumberPassword(user.getConfirmPassword())){
            throw new Exception("匹配帐号密码不合法(必须5-16字节,允许字母数字下划线)");
        }
        User byAccount = userMapper.findByAccount(user.getAccount());
        if (!user.getNewPassword().equals(user.getConfirmPassword())){
            throw new Exception("新密码和确认密码不一致,请重新输入");
        }

        //判断旧密码是否真确正确
        Md5Hash md5Hash = new Md5Hash(user.getPassword(), byAccount.getCodeText(),1024);
        String oldPassword = md5Hash.toHex();
        if(!byAccount.getPassword().equals(oldPassword)){
            throw new Exception("旧密码输入错误,请重新输入)");
        }

        //修改密码
        Md5Hash md5Hash2 = new Md5Hash(user.getNewPassword(), byAccount.getCodeText(),1024);
        userMapper.updatePasswordByAccount(user.getAccount(), md5Hash2.toHex());
        return byAccount;
    }
}

2.登录拦截器

public class JWTInterceptor implements HandlerInterceptor {

    @Autowired
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 1获取客户端传递过来的token
        String strToken = request.getHeader("token");
        if (strToken == null || strToken.length() == 0) {
            // 用户没有登录
            setResponse(response, "用户未登录!!请登陆后再进行操作!!");
            // 拦截
            return false;
        }

        // 2解密Token,时间有没有过期
        Token token = TokenUtil.parseToken(strToken);
        if (token.getStatus() == 1) {
            setResponse(response, "登录已过期!!请重新登陆!!");
            return false;
        }

        // 3是不是一个有效的用户
//        String account = token.getCode();
//        User user = userService.findByAccount(account);
//        if (user == null) {
//            setResponse(response, "当前的用户不是一个有效的用户,请重新登陆!!");
//            return false;
//        }
//        // 4禁用
//        if (user.getStatus() == 1) {
//            setResponse(response, "用户已被禁用,请联系管理员");
//            return false;
//        }

        // 5刷新token 重置有效时间
        strToken = TokenUtil.createToken(token.getCode());
        response.setHeader("token", strToken);
        return true;
    }

    /**
     * 功能描述: 返回json数据
     * @param: [response, msg]
     * @return: void
     * @auther: wanzg
     * @date: 2022-2-15 9:26
     */
    private void setResponse(HttpServletResponse response, String msg) throws IOException {
        APIResult apiResult = APIResult.unauthorized(msg);
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(apiResult);
        response.setContentType("application/json; charset=utf-8");
        response.getWriter().write(json);
    }
}

3.基础的增删改查

<mapper namespace="com.wangzg.community.mapper.UserMapper">
    
    <insert id="save" parameterType="com.wangzg.community.po.User" useGeneratedKeys="true" keyProperty="userId">
        insert into tb_user (user_id,account,password,user_name,user_phone)
        values (#{userId},#{account},#{password},#{userName},#{userPhone})
    </insert>

    <select id="findByAccount" parameterType="string" resultType="com.wangzg.community.po.User">
        select tb_user.*,tb_code.code_text from tb_user,tb_code
        where tb_code.user_id = tb_user.user_id
        and tb_user.account = #{account}
    </select>

    <select id="findUserByAccount" resultMap="userMap">
         select u.*,r.role_id,r.role_name
        from tb_user u LEFT JOIN tb_user_role ur
        on u.user_id = ur.user_id
        LEFT JOIN tb_role r
        on ur.role_id = r.role_id
        WHERE u.account = #{account}
    </select>

    <resultMap id="userMap" type="com.wangzg.community.po.User">
        <id column="user_id" property="userId"></id>
        <result column="account" property="account"></result>
        <result column="password" property="password"></result>
        <result column="user_name" property="userName"></result>
        <result column="user_phone" property="userPhone"></result>
        <result column="user_email" property="userEmail"></result>
        <result column="user_address" property="userAddress"></result>
        <result column="status" property="status"></result>
        <result column="code_text" property="codeText"></result>
        <result column="head" property="head"></result>
        <result column="role_id" property="roleId"></result>
        <result column="role_name" property="roleName"></result>
    </resultMap>

    <select id="findRolesByAccount" parameterType="String" resultMap="userMap">
        select u.user_id, u.account,r.role_id,r.role_name,u.head
        from tb_user u LEFT JOIN tb_user_role ur
        on u.user_id = ur.user_id
        LEFT JOIN tb_role r
        on ur.role_id = r.role_id
        WHERE u.account = #{account}

    </select>

    <select id="findMenuByRoleId" resultType="com.wangzg.community.po.Menu">
        SELECT tb_menu.*,tb_role.role_name from tb_menu
        LEFT JOIN tb_role_menu
        on tb_menu.menu_id = tb_role_menu.menu_id
        LEFT JOIN tb_role
        on tb_role_menu.role_id = tb_role.role_id
        WHERE tb_role.role_id = #{roleId}
    </select>



    <select id="selectAll" resultMap="userMap">
        select tb_user.*,tb_role.* from tb_user LEFT JOIN tb_user_role
        on tb_user.user_id = tb_user_role.user_id
        LEFT JOIN tb_role on
        tb_role.role_id = tb_user_role.role_id
        <where>
            <if test="account != null and account != '' ">   account = #{account}</if>
            <if test="userName != null and userName != ''">  and user_name = #{userName}</if>
            <if test="userPhone != null and userPhone != '' ">  and user_phone = #{userPhone}</if>
        </where>
    </select>

    <update id="deleteUpdate" >
        UPDATE tb_user set `status` = #{status} where user_id = #{userId}
    </update>

    <select id="findByUserId" resultMap="userMap">
        select * from tb_user WHERE user_id = #{userId}
    </select>

    <delete id="deleteById">
        DELETE FROM tb_user where user_id = #{userId}
    </delete>


    <resultMap id="userMapMenu" type="com.wangzg.community.po.User">
        <id column="user_id" property="userId"></id>
        <result column="account" property="account"></result>
        <result column="password" property="password"></result>
        <result column="user_name" property="userName"></result>
        <result column="user_phone" property="userPhone"></result>
        <result column="user_email" property="userEmail"></result>
        <result column="user_address" property="userAddress"></result>
        <result column="status" property="status"></result>
        <result column="code_text" property="codeText"></result>
        <result column="head" property="head"></result>

        <collection property="menus" javaType="list" ofType="com.wangzg.community.po.Menu">
            <id column="menu_id" property="menuId"></id>
            <result column="name" property="name"></result>
            <result column="pid" property="pid"></result>
            <result column="path" property="path"></result>
            <result column="icon" property="icon"></result>
            <result column="page_path" property="pagePath"></result>
            <result column="state" property="state"></result>
        </collection>
    </resultMap>
     <select id="findByAccountMenus" resultMap="userMapMenu">
        SELECT *
		from tb_menu
        LEFT JOIN tb_role_menu
        on tb_menu.menu_id = tb_role_menu.menu_id
        LEFT JOIN tb_role
        on tb_role_menu.role_id = tb_role.role_id
		LEFT JOIN tb_user_role
		on tb_user_role.role_id = tb_role_menu.role_id
		LEFT JOIN tb_user
		on tb_user.user_id = tb_user_role.user_id
		where tb_user.account = #{account}

     </select>

    <update id="updatePasswordByAccount">
        UPDATE tb_user
        set `password` = #{password}
        where account = #{account}
    </update>

    <update id="updateUser">
        update tb_user
        <set>
            <if test="userName != null and userName != ''">
                user_name = #{userName},
            </if>
            <if test="userPhone != null and userPhone != ''">
                user_phone = #{userPhone},
            </if>
            <if test="head != null and head!= ''">
                head = #{head},
            </if>
            <if test="userEmail != null and userEmail != ''">
                user_email =#{userEmail},
            </if>
            <if test="userAddress != null and userAddress != ''">
                user_address = #{userAddress}
            </if>
        </set>
        where
        account = #{account}
    </update>

</mapper>

📝分享的所有Java项目源码均包含(前端+后台+数据库),可做毕业设计或课程设计,欢迎留言分享问题,交流经验
🍅更多优质项目👇🏻👇🏻可点击下方获取🍅文章底部或评论区获取🍅
Java项目精品实战案例《100套》

总结

📣 有源码 查看源码

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

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

相关文章

Linux 资源限制 setrlimit

有的时候为了避免程序毫无意义的占用CPU&#xff08;如死循环&#xff09;、过度占用内存&#xff08;如内存泄漏&#xff09;&#xff0c;我们可以限制程序使用的资源。 下面主要从两个角度限制资源&#xff1a; 限制程序累计运行时长限制可以使用的内存大小 限制资源使用到…

微信小程序 | 小程序系统API调用

&#x1f5a5;️ 微信小程序专栏&#xff1a;小程序系统API调用 &#x1f9d1;‍&#x1f4bc; 个人简介&#xff1a;一个不甘平庸的平凡人&#x1f36c; ✨ 个人主页&#xff1a;CoderHing的个人主页 &#x1f340; 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀️ &#x1f44…

Go语言进阶

一、并发 VS 并行 1: 多线程程序在一个核的CPU上运行 2: 多线程程序在多个核的CPU上运行 Go可以充分发挥多核优势&#xff0c;高效运行。 线程&#xff1a;用户态&#xff0c;轻量级线程&#xff0c;栈MB级别。 协程&#xff1a;内核态&#xff0c;线程内跑多个协程&#xff…

最短路径的java代码实现

1.最短路径定义及性质 有了加权有向图之后&#xff0c;我们立刻就能联想到实际生活中的使用场景&#xff0c;例如在一副地图中&#xff0c;找到顶点a与地点b之间的路径&#xff0c;这条路径可以是距离最短&#xff0c;也可以是时间最短&#xff0c;也可以是费用最小等&#xff…

爬虫的奇技淫巧之ajax-hook

声明 本文仅供学习参考&#xff0c;如有侵权可私信本人删除&#xff0c;请勿用于其他途径&#xff0c;违者后果自负&#xff01; 前言 随着反爬力度的不断升级&#xff0c;现在的爬虫越来越难搞了。诸如加密参数sign、signature、token。面对这种情况传统的方式可以使用自动…

Redis集群系列九 —— 集群伸缩之扩容

集群伸缩 Redis 集群提供了灵活的节点扩容和收缩方案&#xff0c;当有新节点加入时&#xff0c;需要把一部分数据迁移到新节点来达到集群的负载均衡&#xff1b;当旧节点退出时&#xff0c;需要把其上的数据迁移到其他节点上&#xff0c;确保该节点上的数据能够被正常访问。从…

ext4 extent详解3之内核源码流程讲解

本文在前两篇《ext4 extent详解1之示意图演示》和《ext4 extent详解2之内核源码详解》讲解ext4 extent 文章的基础上&#xff0c;本文从内核源码、实例演示等角度详细介绍ext4 extent B树的形成过程&#xff0c;希望看过本文的读者能理解ext4 extent B树的工作原理。 1 &#…

6.3 返回类型和return语句

文章目录无返回值函数有返回值函数值是如何被返回的不要返回局部对象的引用或指针引用返回左值列表初始化返回值主函数main的返回值递归返回数组指针声明一个返回数组指针的函数使用尾置返回类型使用decltypereturn语句终止当前正在执行的函数并将控制权返回到调用该函数的地方…

2022年终总结:点滴积累让我不再迷茫

今年是开始写作的第二年&#xff0c;如果说第一年是起步的话&#xff0c;今年就是开始有了一些小收获了&#xff0c;通过点滴积累让我知道积累的充实感&#xff0c;通过一点一点粉丝或阅读量的积累&#xff0c;增加写作的自信。 今年的收获 首先看一下今年的阅读量和粉丝量: …

cheunghonghui的【22年度总结】

cheunghonghui的【22年度总结】 好久好久没写博客了&#xff0c;看了下后台&#xff0c;上一次发表博客已经是一年半之前&#xff0c;趁着年底&#xff0c;抓紧时间写&#xff08;水&#xff09;一篇不然就要断更了。 【年度工作总结】 1、迭代了未知bug 2、修复了已知bug …

迎接2023,他真的想说“新年快乐”

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;2023年快要到来啦&#xff0c;再此祝大家诸事顺遂&#xff0c;所见所盼皆如愿。 &#x1f514;本文讲解如何使用Java演奏一首歌曲&#xff0c;一起卷起来叭&#xff01; 众所周…

Faster RCNN网络源码解读(Ⅶ) --- RPN网络代码解析(中)RegionProposalNetwork类解析

目录 一、代码作用&#xff08;rpn_function.py&#xff09; 二、代码解析 2.1 RegionProposalNetwork类 2.1.1 初始化函数__init__ 2.1.2 正向传播过程forward 2.1.3 concat_box_prediction_layers函数 2.1.4 permute_and_flatten 2.1.5 filter_proposals 2.1.6 _…

2022 许些遗憾 年终总结

目录回首过去展望未来验收 2022年任务清单 ---------------------------》 2023年 flag2023 展望回首过去 此刻&#xff0c;想想这一年&#xff0c;口罩&#xff0c;38.5℃&#xff0c;艰难时刻&#xff0c;终究在2022最后十天被确诊了“阳”&#xff0c;没有备任何药&#xff…

Linux系列——Linux操作系统安装及服务控制(1)

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.Linux介绍 1.Linux是什么&#xff1f; 2.Linux系统的优点 …

ArcGIS基础实验操作100例--实验31纠正栅格坐标

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验31 纠正栅格坐标 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&…

2023新年祝福代码[css动画特效]

目录 前言 一、jQuery之家 二、2023新年祝福页面 2.1 我的博客和祝福语 2.2 我的博客头像和动态烟花 ​编辑 2.3 背景为动图 三、完整效果图 总结 前言 心态还需努力呀在这里祝大家新的一年里愿望都能实现。2022年已经过去&#xff0c;2022年的遗憾、不开心&#xff…

Spring学习笔记(1)

Spring系统架构 Spring Framework是Spring生态圈中最基础的项目&#xff0c;是其他项目的根基。 Spring Framework系统架构 学习线路 核心概念 IoC( Inversion of Control )控制反转 使用对象时&#xff0c;由主动new产生对象转换为由外部提供对象&#xff0c;此过程中对象…

DoIP协议从入门到精通—Alive check

惯例,为避免自己成为高知识低文化的汉子,分享一段喜欢的文字: 一、Socket 概念 在DoIP(Diagnostic on IP)概念中,通信的核心是Socket(套接字,实际通信的载体),是车载以太网在诊断范畴进行通信的句柄,Socket是支持TCP/IP协议的网络通信的基本操作单元。对于Socket: …

python多进程的理解 multiprocessing Process join run

最近看了下多进程。 一种接近底层的实现方法是使用 os.fork()方法&#xff0c;fork出子进程。但是这样做事有局限性的。比如windows的os模块里面没有 fork() 方法。 windows&#xff1a; 。linux&#xff1a; 另外还有一个模块&#xff1a;subprocess。这个没整过&#xff0c…

Canvas学习笔记 | 图片操作

图片素材 本篇文章的示例采用下图进行图片操作演示。 图片原始尺寸为&#xff1a;640px * 640px。 绘制图片 在Canvas中&#xff0c;我们使用drawImage()方法绘制图片。drawImage()方法有如下3种调用方式&#xff1a; 1.drawImage(image, dx, dy) 2.drawImage(image, dx, d…