基于springboot的智能家居系统

@TOC

springboot198基于springboot的智能家居系统

研究背景与现状

时代的进步使人们的生活实现了部分自动化,由最初的全手动办公已转向手动+自动相结合的方式。比如各种办公系统、智能电子电器的出现,都为人们生活的享受提供帮助。采用新型的自动化方式可以减少手动的办公时间,增加正确率从而增加人们的幸福指数。时代进步中计算机技术的发展尤为突出,渗透进生活的方方面面,各种App、 网站、管理系统、小程序迅速占领市场。

对于智能家居管理的现实问题,大多数家庭采用人工加办公辅助软件的方式进行管理,这类方式对于信息的发布和流程、后续的资料整理工作都是非常大的帮助。但一般都还是针对管理人员使用,如果用户想要操作需要一步一步进行批准,非常复杂。现实智能家居管理工作中缺少一种更为优质、简单的方法途径。

1.2课题实现目的和研究意义

时代的发展也为人们提出了更高的要求,只有不断的学习和发展才可以前进。目前我们正在科技和网络发展的关键点,网络已实现普及。然而还是有大量的企业、机构采用传统的办公方式进行处理事务,当然传统的方式对于小规模的企业、机构来说更为适合,但想要发展就需要以发展的目光来看待问题。如果可以采用更科学、省力的方式进行办公将会带来变革。

智能家居管理关系着家庭的服务享受。工作人员对家具的录入要严格把关,更要考虑到家具的修改、删除问题。以往都是由用户人工统计家具情况,工作人员审核力度不好把控,监督不了家具的实际情况。如果采用共享的平台,把智能家居的相关负责人员都结合到一起,起到共同监管的目的就可以解决这类问题。智能家居的所有信息都可以由管理员直接管理,用户的操作过程也可由相关管理员负责把控,把用户的管理工作实现流程化、清晰化,减少暗箱操作,提供更为透明的工作流程,实现智能家居管理的真正价值。

1.3课题研究内容

  本系统从智能家居管理的工作出发,包括管理员和用户两种权限。管理员的功能为用户管理、家具管理、任务管理、基础数据管理、个人中心管理等,实现系统里信息的全面管控,用户的功能为发布任务和管理家具,两种权限的用户功能相辅相成,不可缺少,共同帮助智能家居管理。本系统实现"放手"、"透明化"管理,使智能家居的管理更加简单、轻松。

1.4论文结构安排

本篇论文的结构分为摘要、目录、正文部分、总结、致谢和参考文献。正文部分为核心。正文部分分为:

第1章绪论,从课题的开发背景、现状、目的意义等进行本课题的介绍;

第2章系统分析,从系统的开发技术、环境、可行性、操作流程等进行系统的详细分析;

第3章系统设计,从系统的功能图、数据库设计、ER图、数据库表进行系统的设计;

第4章系统实现,主要介绍系统的实现界面和实现内容;

第5章系统测试,讲解主要功能的测试过程以及测试结果。

第2章 系统分析

2.1系统开发中使用相关技术介绍

2.1.1Java介绍

Java语言是从C++进行衍生出来的一种新型编程语言,他保留了c++语言中很多核心技术,继承了他的面向对象的优点,而且舍弃了很多缺点,比如在Java语言中去掉了指针,这样可以减少很多错误,还去掉了运算符,这样提高了运行处理效率。还增加了很多优点,添加了垃圾回收功能,提高了代码的使用率,总体来说,Java语言是一个分布式的、高性能的、多线程的开发语言。Java从开发之初就是打算作为一个开放性的语言技术,这就要求需要有很高的兼容性,首先就需要同样的代码程序可以在不同的计算机上运行,还要支持不同的网络,同时还要注重安全性,方便用户使用。Java语言最突出的特点就是面向对象,可以把一个对象当成很多代码状态的物体,然后进行自定义类型进行关联操作,这样进行集合起来的代码就叫对象,面向对象的方法可以使设计根据的简单,方便管理,还可以减少失败。C++最大的一个缺点就是没有垃圾回收机制,通常在编程的过程中,初始化对象时候系统会自动分配一个内存地址,如果不需要这个对象的时候,系统不能进行自动删除和回收,这样造成了很大的内存浪费,导致系统卡顿,会让系统非常的不稳定,严重的话甚至会系统崩溃,而Java语言就是在这个基础上设置了垃圾回收机制,当一个使用过的对象没有引用的时候,系统可以自动删除,回收内存,这样就可以很好的避免了内存泄漏,保障了程序的安全,同时提高了运行效率。

2.1.2Mysql数据库介绍

Mysql数据库是目前比较流行的一种开源数据库,可以支持多种编译器进行在线测试,从而保证了代码的可移植性,而且支持多种操作系统有很好的跨平台性,为编程语言提供所需要的API,可以多线程同时运行,这样有效的减少了内存占用率,提高了使用效率。运行的过程中还能自动优化sql查询算法,这样使数据查询速度达到了显著的提高,而且Mysql数据库还可以作为一个独立的程序在客户端中单独使用,也可以嵌入到其他程序中搭配一起使用。Mysql数据库效率非常的高,可以处理上千万条数据,可以同时支持多种不同的数据引擎,而且是开源的软件,不需要支付任何费用,而且可以进行定制,使用GPL协议进行代码修改,开发属于自己的Mysql系统。综上所述,Mysql数据库是一个非常受欢迎的一个数据库,体积小,速度快,最重要的还是免费,非常适合中小型项目的开发使用。

2.1.3B/s架构介绍

B/s架构是随着网络快速发展而开发出来的一种网络框架,跟传统的cs框架最大的区别就是,直接把代码部署到网络服务器中,这样方便了系统的后期开发和维护,然后用户可以直接通过浏览器进行代码的访问,不需要额外安装任何的软件客户端,简化了用户的使用。B/s结构是指Browser/Server结构,意思就是只需要安装一个服务器就行了, 客户端方面主要就是采用浏览器进行访问,主要是对传统的c/s架构的一种改进,采用www浏览器技术和其他Script语言技术,把系统实现需要的代码全部部署到了服务器上面,是一种新型的架构技术,可以直接借助浏览器进行数据访问和数据交互。最大的优点就是,不需要安装客户端,不受环境影响,可以实时实地的进行访问,其次就是维护非常的方便。当然了有优点也有不可避免的缺点,首先是在访问速度方面,比较受网络的影响,不像C/s架构一样,处理速度非常的快,直接在本机就可以完成数据交互,而B/s需要借助网络才能进行服务器访问,必须保证有顺畅的网络,才能有好的使用体验,其次就是安全性,因为所有数据存储在网络服务器中,比较容易受到攻击,从而造成数据泄漏,这是目前B/s架构存在的最大的弊端。所以说B/s架构适合一些电子商务类的网站,适合比较有用户共享交互的,开放性的网站的设计与开发。所以我开发本系统采用B/s架构是非常适合的,可以达到多人同时登录系统,可以实现信息交互,而且方便随时随地的进行数据访问,而且我对B/s架构开发比较熟悉,所以本系统就采用B/s架构来进行开发设计。

2.1.4Vue技术介绍

Vue技术是主导开发的一种用来创建动态页面的技术。Vue技术通过服务器来响应要求,再根据要求生成Html、Xml来进行转换成Web页面。Vue技术也属于一种脚本语言,常用来搭配Java语言使用,可以和静态的页面一起使用,把静态的页面改成动态的页面。Vue技术在使用时可以转换成Servlet代码,然后再编译成二进制的机器码,当然也可以直接编译成二进制的机器码。Vue技术的特点为简单好用,可以快速的把静态页面变成动态的页面,它使用Javabean来把常用的代码来复制,可以减少编程人员的重复工作,同时Vue技术还拥有很多标签,可以支持更多的外在标签和内在的标签,还可以自定义标签,使编程人员在使用时更加的灵活,加快项目开发的速度。Vue技术的功能非常简单,只负责页面数据,负责页面的传输,所以更加的单纯,不容易出错。

2.1.5 Tomcat服务器介绍

Tomcat服务器属于Apache服务器的一部分。Tomcat服务器作为Java语言项目的运行条件非常受欢迎。因为Tomcat服务器非常小,可以内置到运行软件里使用,不需要单独安装,这样可以减少多种环境的安装,从而简化项目的调试。Tomcat服务器由Sun公司创立,可以处理Html页面,在运行中处理Vue和Servlet页面。

2.1.6Web技术介绍

Web程序一般可以分为静态网站和动态两种形式,前几年的时候一般用的都是静态的,就是网站直接通过Html进行编写出来的,直接放到服务器上,然后通过Http协议用户就可以直接访问网站,相对来说形式比较单一。但是随着技术的发展,很多业务都拓展到了线上进行,单纯的静态网站所保存的数据远远不能满足用户的需求,大多都需要根据用户的需求进行单独生成动态的页面进行反馈,然后根据需要的需求在进行脚本代码的加工处理,然后通过浏览器进行解析,最后反馈给客户,这种形式就是动态的网站。Web客户端的主要功能就是对信息进行展示,可以结合各种编程语言使用,比如像Jtml ,Css 脚本语言等各种技术,而其中最重要的就是Html语言,他是组成Web程序必不可少的一部分,而脚本程序可以嵌入到Html文本里,通过这个流程可以使Html静态网页转换成动态页面,可以很好的提高系统的可交互性。而编写脚本程序常用的就是JavaScript技术,他的突出特点就是变量非常的灵活,而且兼容性好,不需要在单独进行编译,非常方便使用,可以直接用来设计动态交互的网页,不光是可以用来对客户端部分的编写,而且也可以直接通过脚本程序进行服务端的编写,可以很好的解决Web服务端的执行问题。所以说Web服务器主要包含的技术有Java ,Asp,Jsp等,都可以直接通过Web服务端进行页面展现。

2.2系统可行性分析

系统的可行性关系着系统开发的成功和市场,没有经过详细可行性分析的系统开发过程会非常艰难。系统可行性从系统的经济方面、操作方面和技术方面进行分析。

2.2.1经济可行性分析

系统开发所需要的经济主要在系统的成本问题、运行问题和维护问题上。本系统在开发中不需要经济的支撑,所需要的开发软件和设备都是在已有条件上。本系统在运行里所需要的环境也都为免费就可以下载的。本系统在后期的维护上也只需要技术支持就可以完成。所以本系统在经济可行性上可以通过。

2.2.2操作可行性分析

本系统在开发中充分调查了所使用用户的操作习惯和风格,所有的操作流程也都为简单的流程,在操作中也设置了提醒。用户在使用本系统时只要按照提示就可以完成,非常简单。所以本系统在操作可行性上可以通过。

2.2.3技术可行性分析

本系统所需要的技术支持为Java语言,Mysql数据库,Vue技术和Springboot框架等。所使用的技术都为开源成熟的技术,也是目前流行的技术之一。使用这些技术开发的系统可以保证系统的前詹性和稳定性、安全性。所以本系统在技术可性性上可以通过。

2.3系统需求分析

目前计算机、网络技术已进入到各行各业。智能家居做为家庭的重要组成部分更应该身体力行,智能家居管理里的所有工作都是围绕家具而展开,每个家具的档案信息都非常多,如果采用传统的管理方式非常容易造成混乱,而且对于家具的信息查询非常不便。对于家具的性能、数据都需要额外的严谨,如果还是采用传统的管理方式对用户、[家具都做不到百分百的监管,用户的操作也实现不了透明。所以非常需要新的管理方式出现。

2.4系统性能分析

系统在设计时也需要注意系统的性能,一般系统的性能方面包括系统的稳定性、安全性、界面设计方面、操作方面、协调等方面。

  1. 本系统在界面设计方面尊重所有的使用权限,多方面参考不同使用权限的使用习惯以及风格,综合不同的情况整理出符合大众要求的系统界面。做到自己的最大能力;
  2. 在系统的稳定性、安全性方面采用必要的登录验证,不同权限采用不同的账号和密码。为了使系统更为稳定采用成熟的开发环境和技术,在代码编写时尽可能的减少冗余,保证系统的运行效率;
  3. 在系统的操作流程方面,尽可能的采用简单的流程来实现用户要求的反馈,当用户提出需求时,可以用最少的步骤进行提问操作;
  4. 本系统采用数据库和功能界面分开设计,这样可以保证当系统的功能运行出错时不会影响系统里的数据,也就保证了数据的安全。

2.5系统功能分析

系统的功能分析决定了系统的功能设计,完整详细的系统功能分析可以使系统的开发事半功倍。本系统的功能围绕管理员、用户两种权限设计。根据不同权限的不同需求设计出更符合用户要求的功能。本系统中管理员可以管理所有内容,包括使用权限、家具信息、任务信息、基础数据信息等。本基于Springboot的智能家居系统管理员的用例图如下图2-1所示:

图2-1管理员用例图

用户用例为任务管理和家具管理、个人资料管理。用户用例图如下图2-2所示:

图2-2用户用例图

2.6系统操作流程分析

  信息从如何产生到反馈结果的过程可以称为信息的流程。分析好系统的操作流程才可以使系统正确运行不会出现Bug。本系统的流程为管理员先进行登录,登录后管理用户的账号、密码等信息。用户使用注册时的账号密码进行登录,然后进行个人资料的修改、任务发布、家具管理等操作。当用户操作后,管理员可以在管理员界面立即收到操作后的信息,并且可以进行修改。本基于Springboot的智能家居系统的操作流程如下图2-3所示:

图2-3基于Springboot的智能家居系统操作流程图

第3章 系统设计

3.1系统功能结构设计

系统的功能结构是采用树形图来绘制功能设计。根据分析所得,本系统的功能设计为管理员和用户两部分。管理员为高级角色,可以管理系统里的所有信息,包括用户信息。用户功能为发布任务和管理家具。本基于Springboot的智能家居系统的功能结构设计图如下图3-1所示:

图3-1基于Springboot的智能家居系统功能结构图

3.2数据库设计

  数据库为数据的仓库,决定了数据的保存和修改、删除、调用等。数据库的稳定决定了系统里数据的安全。本系统采用Mysql数据库,在建立数据库时采用Root用户名。数据库的建立过程为先进行数据的ER图设计然后进行数据库表的实现。

3.2.1数据ER图设计

数据ER图中记录了关系、实体、属性。实体与实体的关系决定了数据在调用时的正确与否,实体的属性决定了该实体的内容。数据ER图的设计同样重要,也是数据库建立的基础。

通过系统中的功能数据分析,本系统的实体主要有用户、管理员、家具信息、任务信息、类型信息等。

  1. 管理员的ER图中的属性有账号、密码、权限。管理员ER图如下图3-2所示:

图3-2管理员ER图

  1. 用户的ER图里的属性有账号、姓名、编号等,用户的ER图如下图3-3所示:

图3-3用户ER图

  1. 家具信息的ER图里的属性有名称、类别、图片、区域、状态等,家具的ER图如下图3-4所示:

图3-4家具信息ER图

(4)任务的ER图里的属性有家具信息和任务信息等,任务ER图如下图3-5所示:

图3-5任务ER图

  1. 本系统的实体关系图如下图3-6所示:

图3-6实体关系图

3.2.2数据库表设计

数据库表是把ER图进行详细化、实体化。不同的表名下保存着相对应的表信息数据。在数据库表里记录着数据的主键、外键、数据类型、长度等。本基于Springboot的智能家居系统所创建的数据库表有管理员信息表、用户信息表、家具信息表、任务信息表等。本基于Springboot的智能家居系统的数据库表如下表3-1---3-7所示:

表3-1 config

表3-2 dictionary

表3-3 jiaju

|| | :- | 表3-4 renwu

|| | :- | 表3-5 token

|| | :- | 表3-6 users

|| | :- |

表3-7 yonghu

第4章 系统详细实现

4.1用户登录功能的详细实现

用户登录界面起到验证身份的作用,本界面采用图片背景进行设计。在用户登录界面里设置了程序的名称和用户、密码、权限的文本框。在文本框下是登录按钮和用户注册按钮。用户在信息输入完成后可以使用这两个按钮进行相对应的操作。用户登录功能的实现界面如下图4-1所示:

图4-1用户登录实现界面

4.2管理员权限的功能实现

4.2.1个人中心管理功能的详细实现

本功能的作用为修改当前登录用户的登录密码以及信息。本功能可以实现新密码的设置。个人中心管理功能的实现界面如下图4-2所示:

图4-2个人中心管理功能的界面实现

4.2.2用户信息管理功能的详细实现

管理员负责用户信息的审核和管理。用户的密码可以通过本功能重置。管理员查询用户信息的功能实现如下图4-3所示:

图4-3管理员查询用户信息的实现界面

4.2.3家具管理功能的详细实现

管理员可以对家具的信息进行管理、审核。包括增加家具和淘汰家具,管理员查询家具信息的实现界面如下图4-4所示:

图4-4管理员查询家具信息的实现界面

4.2.4任务管理功能的详细实现

管理员可以查询用户发布的任务指令,并对任务进行修改等必要操作。管理员查询任务功能的实现界面如下图4-5所示:

图4-5管理员查询任务的实现界面

4.2.5基础数据管理功能的详细界面实现

管理员可以实现家具类型、区域类型的管理。管理员添加家具类型的实现界面如下图4-6所示:

图4-6管理员添加家具类型信息功能的运行界面

4.3用户权限的功能实现

4.3.1家具管理功能的详细实现

用户可以实现家具的查询和家具的新增、修改、删除。家具查询功能实现界面如下图4-7所示:

图4-7家具查询功能的实现界面

4.3.2任务管理功能的详细实现

用户可以发布任务,填写任务单就可以实现任务的发布。用户发布任务功能的实现界面如下图4-8所示:

图4-8用户发布任务功能的实现界面

第5章 系统测试

系统测试

InterceptorConfig.java
package com.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import com.interceptor.AuthorizationInterceptor;

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport{
	
	@Bean
    public AuthorizationInterceptor getAuthorizationInterceptor() {
        return new AuthorizationInterceptor();
    }
	
	@Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getAuthorizationInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**");
        super.addInterceptors(registry);
	}
	
	/**
	 * springboot 2.0配置WebMvcConfigurationSupport之后,会导致默认配置被覆盖,要访问静态资源需要重写addResourceHandlers方法
	 */
	@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/**")
        .addResourceLocations("classpath:/resources/")
        .addResourceLocations("classpath:/static/")
        .addResourceLocations("classpath:/admin/")
        .addResourceLocations("classpath:/img/")
        .addResourceLocations("classpath:/front/")
        .addResourceLocations("classpath:/public/");
		super.addResourceHandlers(registry);
    }
}
JiajuController.java
package com.controller;

import java.io.File;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.JSONObject;
import java.util.*;
import org.springframework.beans.BeanUtils;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.ContextLoader;
import javax.servlet.ServletContext;
import com.service.TokenService;
import com.utils.*;
import java.lang.reflect.InvocationTargetException;

import com.service.DictionaryService;
import org.apache.commons.lang3.StringUtils;
import com.annotation.IgnoreAuth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.entity.*;
import com.entity.view.*;
import com.service.*;
import com.utils.PageUtils;
import com.utils.R;
import com.alibaba.fastjson.*;

/**
 * 家具
 * 后端接口
 * @author
 * @email
*/
@RestController
@Controller
@RequestMapping("/jiaju")
public class JiajuController {
    private static final Logger logger = LoggerFactory.getLogger(JiajuController.class);

    @Autowired
    private JiajuService jiajuService;


    @Autowired
    private TokenService tokenService;
    @Autowired
    private DictionaryService dictionaryService;

    //级联表service
    @Autowired
    private YonghuService yonghuService;



    /**
    * 后端列表
    */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){
        logger.debug("page方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));
        String role = String.valueOf(request.getSession().getAttribute("role"));
        if(false)
            return R.error(511,"永不会进入");
        else if("用户".equals(role))
            params.put("yonghuId",request.getSession().getAttribute("userId"));
        params.put("jiajuDeleteStart",1);params.put("jiajuDeleteEnd",1);
        if(params.get("orderBy")==null || params.get("orderBy")==""){
            params.put("orderBy","id");
        }
        PageUtils page = jiajuService.queryPage(params);

        //字典表数据转换
        List<JiajuView> list =(List<JiajuView>)page.getList();
        for(JiajuView c:list){
            //修改对应字典表字段
            dictionaryService.dictionaryConvert(c, request);
        }
        return R.ok().put("data", page);
    }

    /**
    * 后端详情
    */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id, HttpServletRequest request){
        logger.debug("info方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
        JiajuEntity jiaju = jiajuService.selectById(id);
        if(jiaju !=null){
            //entity转view
            JiajuView view = new JiajuView();
            BeanUtils.copyProperties( jiaju , view );//把实体数据重构到view中

                //级联表
                YonghuEntity yonghu = yonghuService.selectById(jiaju.getYonghuId());
                if(yonghu != null){
                    BeanUtils.copyProperties( yonghu , view ,new String[]{ "id", "createTime", "insertTime", "updateTime"});//把级联的数据添加到view中,并排除id和创建时间字段
                    view.setYonghuId(yonghu.getId());
                }
            //修改对应字典表字段
            dictionaryService.dictionaryConvert(view, request);
            return R.ok().put("data", view);
        }else {
            return R.error(511,"查不到数据");
        }

    }

    /**
    * 后端保存
    */
    @RequestMapping("/save")
    public R save(@RequestBody JiajuEntity jiaju, HttpServletRequest request){
        logger.debug("save方法:,,Controller:{},,jiaju:{}",this.getClass().getName(),jiaju.toString());

        String role = String.valueOf(request.getSession().getAttribute("role"));
        if(false)
            return R.error(511,"永远不会进入");
        else if("用户".equals(role))
            jiaju.setYonghuId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));

        Wrapper<JiajuEntity> queryWrapper = new EntityWrapper<JiajuEntity>()
            .eq("yonghu_id", jiaju.getYonghuId())
            .eq("jiaju_uuid_number", jiaju.getJiajuUuidNumber())
            .eq("jiaju_name", jiaju.getJiajuName())
            .eq("jiaju_types", jiaju.getJiajuTypes())
            .eq("quyu_types", jiaju.getQuyuTypes())
            .eq("zhuangtai_types", jiaju.getZhuangtaiTypes())
            .eq("jiaju_delete", jiaju.getJiajuDelete())
            ;

        logger.info("sql语句:"+queryWrapper.getSqlSegment());
        JiajuEntity jiajuEntity = jiajuService.selectOne(queryWrapper);
        if(jiajuEntity==null){
            jiaju.setJiajuDelete(1);
            jiaju.setCreateTime(new Date());
            jiajuService.insert(jiaju);
            return R.ok();
        }else {
            return R.error(511,"表中有相同数据");
        }
    }

    /**
    * 后端修改
    */
    @RequestMapping("/update")
    public R update(@RequestBody JiajuEntity jiaju, HttpServletRequest request){
        logger.debug("update方法:,,Controller:{},,jiaju:{}",this.getClass().getName(),jiaju.toString());

        String role = String.valueOf(request.getSession().getAttribute("role"));
//        if(false)
//            return R.error(511,"永远不会进入");
//        else if("用户".equals(role))
//            jiaju.setYonghuId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));
        //根据字段查询是否有相同数据
        Wrapper<JiajuEntity> queryWrapper = new EntityWrapper<JiajuEntity>()
            .notIn("id",jiaju.getId())
            .andNew()
            .eq("yonghu_id", jiaju.getYonghuId())
            .eq("jiaju_uuid_number", jiaju.getJiajuUuidNumber())
            .eq("jiaju_name", jiaju.getJiajuName())
            .eq("jiaju_types", jiaju.getJiajuTypes())
            .eq("quyu_types", jiaju.getQuyuTypes())
            .eq("zhuangtai_types", jiaju.getZhuangtaiTypes())
            .eq("jiaju_delete", jiaju.getJiajuDelete())
            ;

        logger.info("sql语句:"+queryWrapper.getSqlSegment());
        JiajuEntity jiajuEntity = jiajuService.selectOne(queryWrapper);
        if("".equals(jiaju.getJiajuPhoto()) || "null".equals(jiaju.getJiajuPhoto())){
                jiaju.setJiajuPhoto(null);
        }
        if(jiajuEntity==null){
            jiajuService.updateById(jiaju);//根据id更新
            return R.ok();
        }else {
            return R.error(511,"表中有相同数据");
        }
    }

    /**
    * 删除
    */
    @RequestMapping("/delete")
    public R delete(@RequestBody Integer[] ids){
        logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());
        ArrayList<JiajuEntity> list = new ArrayList<>();
        for(Integer id:ids){
            JiajuEntity jiajuEntity = new JiajuEntity();
            jiajuEntity.setId(id);
            jiajuEntity.setJiajuDelete(2);
            list.add(jiajuEntity);
        }
        if(list != null && list.size() >0){
            jiajuService.updateBatchById(list);
        }
        return R.ok();
    }


    /**
     * 批量上传
     */
    @RequestMapping("/batchInsert")
    public R save( String fileName, HttpServletRequest request){
        logger.debug("batchInsert方法:,,Controller:{},,fileName:{}",this.getClass().getName(),fileName);
        Integer yonghuId = Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId")));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            List<JiajuEntity> jiajuList = new ArrayList<>();//上传的东西
            Map<String, List<String>> seachFields= new HashMap<>();//要查询的字段
            Date date = new Date();
            int lastIndexOf = fileName.lastIndexOf(".");
            if(lastIndexOf == -1){
                return R.error(511,"该文件没有后缀");
            }else{
                String suffix = fileName.substring(lastIndexOf);
                if(!".xls".equals(suffix)){
                    return R.error(511,"只支持后缀为xls的excel文件");
                }else{
                    URL resource = this.getClass().getClassLoader().getResource("static/upload/" + fileName);//获取文件路径
                    File file = new File(resource.getFile());
                    if(!file.exists()){
                        return R.error(511,"找不到上传文件,请联系管理员");
                    }else{
                        List<List<String>> dataList = PoiUtil.poiImport(file.getPath());//读取xls文件
                        dataList.remove(0);//删除第一行,因为第一行是提示
                        for(List<String> data:dataList){
                            //循环
                            JiajuEntity jiajuEntity = new JiajuEntity();
//                            jiajuEntity.setYonghuId(Integer.valueOf(data.get(0)));   //用户 要改的
//                            jiajuEntity.setJiajuUuidNumber(data.get(0));                    //家具编号 要改的
//                            jiajuEntity.setJiajuName(data.get(0));                    //家具名称 要改的
//                            jiajuEntity.setJiajuPhoto("");//详情和图片
//                            jiajuEntity.setJiajuTypes(Integer.valueOf(data.get(0)));   //家具类型 要改的
//                            jiajuEntity.setQuyuTypes(Integer.valueOf(data.get(0)));   //区域 要改的
//                            jiajuEntity.setJiajuContent("");//详情和图片
//                            jiajuEntity.setZhuangtaiTypes(Integer.valueOf(data.get(0)));   //状态 要改的
//                            jiajuEntity.setJiajuDelete(1);//逻辑删除字段
//                            jiajuEntity.setCreateTime(date);//时间
                            jiajuList.add(jiajuEntity);


                            //把要查询是否重复的字段放入map中
                                //家具编号
                                if(seachFields.containsKey("jiajuUuidNumber")){
                                    List<String> jiajuUuidNumber = seachFields.get("jiajuUuidNumber");
                                    jiajuUuidNumber.add(data.get(0));//要改的
                                }else{
                                    List<String> jiajuUuidNumber = new ArrayList<>();
                                    jiajuUuidNumber.add(data.get(0));//要改的
                                    seachFields.put("jiajuUuidNumber",jiajuUuidNumber);
                                }
                        }

                        //查询是否重复
                         //家具编号
                        List<JiajuEntity> jiajuEntities_jiajuUuidNumber = jiajuService.selectList(new EntityWrapper<JiajuEntity>().in("jiaju_uuid_number", seachFields.get("jiajuUuidNumber")).eq("jiaju_delete", 1));
                        if(jiajuEntities_jiajuUuidNumber.size() >0 ){
                            ArrayList<String> repeatFields = new ArrayList<>();
                            for(JiajuEntity s:jiajuEntities_jiajuUuidNumber){
                                repeatFields.add(s.getJiajuUuidNumber());
                            }
                            return R.error(511,"数据库的该表中的 [家具编号] 字段已经存在 存在数据为:"+repeatFields.toString());
                        }
                        jiajuService.insertBatch(jiajuList);
                        return R.ok();
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            return R.error(511,"批量插入数据异常,请联系管理员");
        }
    }






}
PoiUtil.java
package com.utils;

import org.apache.commons.io.FileUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件导入到处
 */
public class PoiUtil {
    /**
     * 导入
     *
     * @param url
     * @return
     * @throws Exception
     */
    public static List<List<String>> poiImport(String url) throws Exception {
        List<List<String>> list = new ArrayList<>();
        // 创建Excel 读取文件内容
        HSSFWorkbook workbook = new HSSFWorkbook(FileUtils.openInputStream(new File(url)));
        /**
         * 第一种方式读取Sheet页
         */
//      HSSFSheet sheet = workbook.getSheet("Sheet0");
        /**
         * 第二种方式读取Sheet页
         */
        HSSFSheet sheet = workbook.getSheetAt(0);//获取工作表
        for (int i = 0; i < sheet.getLastRowNum()+1; i++) {
            HSSFRow row = sheet.getRow(i);//获取行
            List<String> rowlist = new ArrayList<>();//行数据
            for (int j = 0; j < row.getLastCellNum(); j++) {
                HSSFCell cell = row.getCell(j);
                cell.setCellType(Cell.CELL_TYPE_STRING);
                String value = cell.getStringCellValue();
                rowlist.add(value);//行中数据添加到行中
            }
            list.add(rowlist);//将行数据添加到list中
        }
        return list;
    }






    // 导出
    public static void poiExport(List<List<String>> list, String url) throws Exception {
        //创建Excel工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        //创建一个工作表shheet
        HSSFSheet sheet = workbook.createSheet();
        for (int i = 0; i < list.size(); i++) {
            HSSFRow row = sheet.createRow(i);
            List<String> dataList = list.get(i);
            for (int j = 0; j < dataList.size(); j++) {
                HSSFCell cell = row.createCell(j);
                cell.setCellValue(dataList.get(j));
            }

        }
        FileOutputStream stream = FileUtils.openOutputStream(new File(url));
        workbook.write(stream);
        stream.close();
    }


    public static void main(String[] args) {
        try {
            //导入
            List<List<String>> lists = PoiUtil.poiImport("C:/Users/Administrator/Desktop/工作1.xls");
            System.out.println();


            //导出

            PoiUtil.poiExport(lists, "C:/Users/Administrator/Desktop/工作1.xls");

//
//            List<List<String>> list = new ArrayList<>();
//            ArrayList<String> dataList = new ArrayList<>();
//            dataList.add("标题1");
//            dataList.add("标题2");
//            dataList.add("标题3");
//            list.add(dataList);
//            // 追加数据
//            for (int i = 1; i < 10; i++) {// 这里的int 起始是1 也就是第二行开始
//                ArrayList<String> dataList111 = new ArrayList<>();
//                dataList111.add("内容" + i);
//                dataList111.add("内容1111111121222222222333333333377777777411111111477777777" + i);
//                dataList111.add("内容" + i);
//                list.add(dataList111);
//            }
//            PoiUtil.poiExport(list, "C:/Users/Administrator/Desktop/工作1.xls");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Editor.vue
<template>
  <div>
    <!-- 图片上传组件辅助-->
    <el-upload
      class="avatar-uploader"
      :action="getActionUrl"
      name="file"
      :headers="header"
      :show-file-list="false"
      :on-success="uploadSuccess"
      :on-error="uploadError"
      :before-upload="beforeUpload"
    ></el-upload>

    <quill-editor
      class="editor"
      v-model="content"
      ref="myQuillEditor"
      :options="editorOption"
      @blur="onEditorBlur($event)"
      @focus="onEditorFocus($event)"
      @change="onEditorChange($event)"
    ></quill-editor>
  </div>
</template>
<script>
// 工具栏配置
const toolbarOptions = [
  ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
  ["blockquote", "code-block"], // 引用  代码块
  [{ header: 1 }, { header: 2 }], // 1、2 级标题
  [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
  [{ script: "sub" }, { script: "super" }], // 上标/下标
  [{ indent: "-1" }, { indent: "+1" }], // 缩进
  // [{'direction': 'rtl'}],                         // 文本方向
  [{ size: ["small", false, "large", "huge"] }], // 字体大小
  [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
  [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
  [{ font: [] }], // 字体种类
  [{ align: [] }], // 对齐方式
  ["clean"], // 清除文本格式
  ["link", "image", "video"] // 链接、图片、视频
];

import { quillEditor } from "vue-quill-editor";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";

export default {
  props: {
    /*编辑器的内容*/
    value: {
      type: String
    },
    action: {
      type: String
    },
    /*图片大小*/
    maxSize: {
      type: Number,
      default: 4000 //kb
    }
  },

  components: {
    quillEditor
  },

  data() {
    return {
      content: "",
      quillUpdateImg: false, // 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示
      editorOption: {
        placeholder: "",
        theme: "snow", // or 'bubble'
        modules: {
          toolbar: {
            container: toolbarOptions,
            // container: "#toolbar",
            handlers: {
              image: function(value) {
                if (value) {
                  // 触发input框选择图片文件
                  document.querySelector(".avatar-uploader input").click();
                } else {
                  this.quill.format("image", false);
                }
              }
              // link: function(value) {
              //   if (value) {
              //     var href = prompt('请输入url');
              //     this.quill.format("link", href);
              //   } else {
              //     this.quill.format("link", false);
              //   }
              // },
            }
          }
        }
      },
      // serverUrl: `${base.url}sys/storage/uploadSwiper?token=${storage.get('token')}`, // 这里写你要上传的图片服务器地址
      header: {
        // token: sessionStorage.token
       'Token': this.$storage.get("Token")
      } // 有的图片服务器要求请求头需要有token
    };
  },
  computed: {
    // 计算属性的 getter
    getActionUrl: function() {
      // return this.$base.url + this.action + "?token=" + this.$storage.get("token");
	  this.setContent(this.value);
      return `/${this.$base.name}/` + this.action;
    }
  },
  methods: {
    setContent(value) {
        this.content = value;
    },
    onEditorBlur() {
      //失去焦点事件
    },
    onEditorFocus() {
      //获得焦点事件
    },
    onEditorChange() {
      // console.log(this.content);
      // 内容改变事件
      this.$emit("input", this.content);
    },
    // 富文本图片上传前
    beforeUpload() {
      // 显示loading动画
      this.quillUpdateImg = true;
    },

    uploadSuccess(res, file) {
      // res为图片服务器返回的数据
      // 获取富文本组件实例
      let quill = this.$refs.myQuillEditor.quill;
      // 如果上传成功
      if (res.code === 0) {
        // 获取光标所在位置
        let length = quill.getSelection().index;
        // 插入图片  res.url为服务器返回的图片地址
        quill.insertEmbed(length, "image", this.$base.url+ "upload/" +res.file);
        // 调整光标到最后
        quill.setSelection(length + 1);
      } else {
        this.$message.error("图片插入失败");
      }
      // loading动画消失
      this.quillUpdateImg = false;
    },
    // 富文本图片上传失败
    uploadError() {
      // loading动画消失
      this.quillUpdateImg = false;
      this.$message.error("图片插入失败");
    }
  }
};
</script> 

<style>
.editor {
  line-height: normal !important;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
  content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
  border-right: 0px;
  content: "保存";
  padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode="video"]::before {
  content: "请输入视频地址:";
}
.ql-container {
	height: 400px;
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: "14px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
  content: "10px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
  content: "18px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
  content: "32px";
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "文本";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: "标题6";
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: "标准字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
  content: "衬线字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
  content: "等宽字体";
}
</style>
相关推荐
爬山算法21 分钟前
Maven(28)如何使用Maven进行依赖解析?
java·maven
hlsd#28 分钟前
go mod 依赖管理
开发语言·后端·golang
陈大爷(有低保)33 分钟前
三层架构和MVC以及它们的融合
后端·mvc
亦世凡华、33 分钟前
【启程Golang之旅】从零开始构建可扩展的微服务架构
开发语言·经验分享·后端·golang
河西石头34 分钟前
一步一步从asp.net core mvc中访问asp.net core WebApi
后端·asp.net·mvc·.net core访问api·httpclient的使用
2401_857439691 小时前
SpringBoot框架在资产管理中的应用
java·spring boot·后端
怀旧6661 小时前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节
李老头探索1 小时前
Java面试之Java中实现多线程有几种方法
java·开发语言·面试
芒果披萨1 小时前
Filter和Listener
java·filter
qq_4924484461 小时前
Java实现App自动化(Appium Demo)
java