实战项目——智慧社区(一)

news/2024/5/11 21:06:01/文章来源:https://blog.csdn.net/weixin_47480200/article/details/137607612

1、项目介绍

系统功能

登录、修改密码、登出

(1)首页

        (1.1)数据统计:小区人员统计对比图,占比图

(2)物业管理

        (2.1)小区管理:小区数据的增删改查

                (2.1.1)摄像头管理:小区摄像头数据的增删改查

        (2.2)居民管理:居民数据的增删改查,居民人脸采集,Excel 数据导入,Excel 数据导出

        (2.3)小区地图:所有小区在地图上的分布情况

(3)门禁管理

       (3.1) 人脸识别:居民出入小区人脸识别功能

        (3.2)出入记录:所有居民出入小区的人脸识别记录查询

        (3.3)访客登记:访客数据的增删改查,进入登记,离开登记

(4)系统管理

        (4.1)用户管理:用户数据的增删改查,给用户赋予角色设置不同的管理权限

        (4.2)角色管理:角色数据的增删改查,给角色赋予权限

        (4.3)菜单管理:菜单数据的增删改查,不同角色可设置不同的菜单权限

        (4.4)日志管理:实时记录系统所有操作的日志,为排查问题提供依据

技术栈描述

前端:Vue+ElementUI+BaiduMap+ECharts

后端:SpringBoot+SpringMVC+MyBatisPlus+Spring Data Redis+ Swagger

第三方服务:人脸识别,腾讯AI接口(后端)

​                         BaiduMap,ECharts(前端)

数据库:MySQL 数据库存储、Redis 缓存

其他技术:POI Excel 文件导入导出、Swagger 接口文档管理、JWT 登录认证、Spring AOP 日志管理、前端代理解决跨域问题

2、登录模块

数据表设计

用户信息表(user)

用于存储登录用户的登录信息

实现思路

①获取验证码:首先借助UUID或者其它工具生成一个符合要求的验证码;然后存入到缓存数据库redis当中,并设置超时时间;最后将验证码返回给前端

②登录验证:第一步在redis中查询验证码,验证验证码是否有效和正常 ;第二步验证用户名;第三步验证密码(JWT加密,生成token);第四步验证用户状态是否正常;第五步创建token,生成令牌,将token存入到redis中;第六步获取token的过期时间,将token和过期时间返回给前端,允许用户登录并访问首页

获取验证码

①redis配置,redis用于存储验证码和登录生成的token

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/community?useUnicode=true&characterEncoding=utf-8username: rootpassword: 123456jackson:time-zone: GMT+8date-format: yyyy-MM-dd HH:mm:ssredis:open: truedatabase: 2host: localhostport: 6379

②导入验证码的依赖

<dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version>
</dependency><!--工具包-->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.2.4</version>
</dependency>

③获取生成验证码

    @Autowiredprivate RedisTemplate redisTemplate;/**    * 获取生成验证码* @return*/@GetMapping("/captcha")public Result getCaptcha(){//1、借助UUID或者其它工具生成一个符合要求的验证码//2、存入到缓存数据库redis当中,并设置超时时间//3、验证码返回给前端//利用生成验证码图片的工具类,指定宽和高,以及生成的验证码数量4SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);//将生成的验证码图片转成小写字符串String code = specCaptcha.text().toLowerCase();//通过工具类产生一个UUID值,当成验证码信息存储在redis数据库中的主键String uuid = IdUtil.simpleUUID();//存入redis并设置过期时间为2分钟this.redisTemplate.opsForValue().set(uuid, code, 120, TimeUnit.SECONDS);Map<String, String> map = new HashMap<String, String>(3);map.put("uuid", uuid);map.put("code", code);//将验证码图片转成base64的图片信息,方便前端将图片解析进行显示map.put("captcha", specCaptcha.toBase64());//响应200,就是请求到达了控制器return Result.ok().put("data", map);}

登录验证

①jwt配置,jwt用于验证用户的身份和权限,生成token

jwt:secret: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4K67DMlSPXbgG0MPp0gHexpire: 86400000#  expire: 10000subject: door

 ②导入jwt依赖

        <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>

③jwt工具包

package com.qcby.community.util;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;import java.util.Date;
import java.util.UUID;@ConfigurationProperties(prefix = "jwt")
@Component
public class JwtUtil {private long expire;private String secret;private String subject;/*** 生成token** @param userId* @return*/public String createToken(String userId) {String token = Jwts.builder()//载荷:自定义信息.claim("userId", userId)//载荷:默认信息.setSubject(subject) //令牌主题.setExpiration(new Date(System.currentTimeMillis() + expire)) //过期时间.setId(UUID.randomUUID().toString())//签名哈希.signWith(SignatureAlgorithm.HS256, secret)//组装jwt字符串.compact();return token;}//Token校验public boolean checkToken(String token){if(StringUtils.isEmpty(token)){return false;}try {Jws<Claims> claimsJws = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);} catch (Exception e) {return false;}return true;}public long getExpire() {return expire;}public void setExpire(long expire) {this.expire = expire;}public String getSecret() {return secret;}public void setSecret(String secret) {this.secret = secret;}public String getSubject() {return subject;}public void setSubject(String subject) {this.subject = subject;}
}

④登录请求处理

    @Autowiredprivate JwtUtil jwtUtil;/*** 前端发送过来的登录请求* @param loginForm* @param session* @return*/@PostMapping("/login")public Result login(@RequestBody LoginForm loginForm, HttpSession session){//1、查询redis验证,验证码是否有效和正常//2、验证用户名//3、验证密码(JWT加密,生成token)//4、验证用户状态是否正常//5、允许用户登录并访问首页//验证码校验String code = (String) this.redisTemplate.opsForValue().get(loginForm.getUuid());//判断验证码是否有效if(code == null){
//            return Result.error("验证码已过期");return Result.ok().put("status", "fail").put("date", "验证码已过期");}//判断验证码是否正确if(!code.equals(loginForm.getCaptcha())){
//            return Result.error("验证码错误");return Result.ok().put("status", "fail").put("date", "验证码错误");}//判断用户名是否正确QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("username", loginForm.getUsername());User user = this.userService.getOne(queryWrapper);if(user == null){return Result.error("用户名错误");}//判断密码是否正确,密码加密之后比对String password = SecureUtil.sha256(loginForm.getPassword());if(!password.equals(user.getPassword())){return Result.error("密码错误");}//验证用户是否可用if(user.getStatus() == 0) {return Result.error("账号已被锁定,请联系管理员");}//登录成功session.setAttribute("user", user);//创建token,生成令牌String token = this.jwtUtil.createToken(String.valueOf(user.getUserId()));//将token存入redis,每一次访问不需要重复登录,直接验证令牌this.redisTemplate.opsForValue().set("communityuser-"+user.getUserId(), token,jwtUtil.getExpire());Map<String,Object> map = new HashMap<>();map.put("token", token);map.put("expire", jwtUtil.getExpire());
//        LogAspect.user = user;return Result.ok().put("data", map);}

界面

3、修改密码

实现思路

①发送更新密码请求,弹出更新密码弹出层

②前端密码格式验证,新旧密码是否一致验证

③修改密码:第一步获取session中的用户信息;第二步将根据用户查询的密码和前端传来的旧密码进行比较,如果相等,将新密码加密后在数据库中更新密码字段信息,密码更新成功,返回。

修改密码请求处理

     /*** 修改密码* @return*/@PutMapping("/updatePassword")public Result updatePassword(@RequestBody UpdatePasswordForm updatePasswordForm, HttpSession session){User user = (User)session.getAttribute("user");String pwd = user.getPassword();String password = SecureUtil.sha256(updatePasswordForm.getPassword());if(pwd.equals(password)){String newpassword = SecureUtil.sha256(updatePasswordForm.getNewPassword());user.setPassword(newpassword);if(userService.updateById(user)){return Result.ok().put("status","success");}return Result.error("更新密码失败");}return Result.ok().put("status","passwordError");}

界面 

4、登出模块

实现思路

①登出请求:将当前session设置为无效

②将token设置为空

③将router设置为空

④将cookie里面的token信息清空

⑤返回登录页面

登出请求处理

     /*** 用户退出* @param session* @return*/@PostMapping("/logout")public Result logOut(HttpSession session){session.invalidate();return Result.ok();}

5、首页

登录成功后,根据当前的登录用户来动态加载对应的菜单列表(路由),显示该用户能访问的菜单;并且同时查看小区数据统计,通过柱状图和饼状图展示

数据表设计

角色表(role)

用于存储用户的角色信息

用户角色关联表(user_role)

用户存储角色和用户的关联信息

 

菜单表(menu)

用于存储前端展示的菜单信息,其中parent_id代表父级菜单的序号,0代表一级菜单,name代表菜单名称,path代表菜单url,component代表组件路径,icon代表组件图标

角色菜单关联表(role_menu) 

用于存储角色拥有的菜单权限信息

小区信息表(community) 

用户存储小区信息,其中term_count代表楼栋数量,seq代表排序,lng和lat分别代表经度和纬度

住户表(person)

存储小区的住户信息,其中state代表人脸录入状态,2代表已录入,1代表未录入

加载动态路由

实现思路

①通过session获取用户信息

②根据userId获取角色名称,需要在user_role表和role表中联表查询

③根据userId获取用户的权限菜单:

第一步:根据用户的id查询该用户所对应的角色以及该角色所对应的菜单,需要user_role、user_menu、menu三个表联表查询;

第二步:按照查询出来的菜单进行封装,一个一级菜单的信息封装进一个列表,此菜单下的二级菜单的信息封装进此列表的子列表中,若有三级菜单以此类推进行封装

④返回用户信息、角色名称和用户的权限菜单信息,格式如下

 "data": {
        "userId": 1,
        "username": "admin", 
        "password": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
        "userType": 1, 
        "realName": "管理员", 
        "contact": "", 
        "mobile": "15679711120", 
        "status": 1, 
        "roleIdList": null
    },
    "roles": "超级管理员",
    "routers": [
        {
            "name": "系统管理",
            "path": "/sys",
            "hidden": "false",
            "redirect": "noRedirect",
            "component": "Layout",
            "alwaysShow": true,
            "meta": {
                "title": "系统管理",
                "icon": "system"
            },
            "children": [
                {
                    "name": "管理员管理",
                    "path": "/user",
                    "hidden": "false",
                    "component": "sys/user/index",
                    "meta": {
                        "title": "管理员管理",
                        "icon": "user"
                    }
                }
            ]
        }
    ]

封装返回的routers信息MenuRouterVO

@Data
public class MenuRouterVO {private String name;private String path;private String component;private String hidden;private String redirect = "noRedirect";private Boolean alwaysShow = true;private MetaVO meta;private List<ChildMenuRouterVO> children;
}@Data
public class ChildMenuRouterVO {private String name;private String path;private String component;private String hidden;private MetaVO meta;
}@Data
public class MetaVO {private String title;private String icon;
}

加载动态路由controller请求

    /*** 通过登录的用于加载动态路由* 显示该用户能访问的菜单* @param session* @return*/@GetMapping("/getRouters")public Result getRouters(HttpSession session){//获取用户名称User user = (User)session.getAttribute("user");//获取用户的角色名称String roles = roleMapper.getRoleNameByUserId(user.getUserId());//获取用户的权限菜单List<MenuRouterVO> routers = this.menuService.getMenuRouterByUserId(user.getUserId());return Result.ok().put("data", user).put("roles", roles).put("routers",routers);}

获取用户的角色名称的mapper

//根据userId获取角色名称@Select("SELECT role_name FROM role, user_role where user_role.role_id=role.role_id and user_role.user_id=#{userId}")public String getRoleNameByUserId(Integer userId);

获取用户的菜单信息service

@Autowiredprivate MenuMapper menuMapper;@Overridepublic List<MenuRouterVO> getMenuRouterByUserId(Integer userId) {//1.根据用户的id查询该用所对应的角色以及该角色所对应的菜单List<Menu> menuList = this.menuMapper.getMenusByUserId(userId);//2.创建一个集合List<MenuRouterVO> 最终的集合List<MenuRouterVO> list = new ArrayList<>();//3.遍历该用户所能查看的所有菜单找到一级菜单封装进MenuRouterVOfor (Menu menu : menuList) {//挑选出父级菜单if (menu.getParentId() == 0) {MenuRouterVO menuRouterVO = new MenuRouterVO();//给父级菜单对象赋值,bean实体类的封装工具类,框架提供//将源对象menu中的相同属性赋值给新对象menuRouterVOBeanUtils.copyProperties(menu, menuRouterVO);//再将没有的属性进行赋值MetaVO metaVO = new MetaVO();metaVO.setTitle(menu.getName());metaVO.setIcon(menu.getIcon());menuRouterVO.setMeta(metaVO);//生成childrenInteger menuId = menu.getMenuId();//4.不是一级菜单的继续遍历找到属于哪个一级菜单下挂在该菜单下List<ChildMenuRouterVO> children = new ArrayList<>();for (Menu child : menuList) {if(child.getParentId() == menuId){//5.封装子菜单ChildMenuRouterVO  在放进集合List<ChildMenuRouterVO>ChildMenuRouterVO childVO = new ChildMenuRouterVO();BeanUtils.copyProperties(child, childVO);MetaVO childMetaVO = new MetaVO();childMetaVO.setTitle(child.getName());childMetaVO.setIcon(child.getIcon());childVO.setMeta(childMetaVO);children.add(childVO);}}//6.将子菜单集合挂在MenuRouterVO的children的集合属性下menuRouterVO.setChildren(children);//7.将每一个MenuRouterVO放进大集合list.add(menuRouterVO);}}return list;}

获取用户的菜单信息mapper

​
@Repository
public interface MenuMapper extends BaseMapper<Menu> {@Select({"select m.menu_id,m.parent_id,m.name,m.path,m.component," +"m.menu_type,m.status,m.icon,m.sort,m.hidden from " +"user_role ur,role_menu rm,menu m where ur.role_id = rm.role_id" +" and rm.menu_id = m.menu_id " +"and ur.user_id = #{userId} order by m.sort"})public List<Menu> getMenusByUserId(Integer userId);
}​

查看小区数据统计

实现思路

查询出所有的小区名称,以及每个小区的对应的住户数量,并将小区名称与其对应的住户数量封装成单个list,从小区信息表community和住户表person中联表查询出来,返回数据如下所示:

"data": {
        "names": [
            "栖海澐颂",
            "宸悦国际",
            "流星花园二区",
            "农学院家属院",
            "金达园",
            "建发城建·文源府",
            "北清云际"
        ],
        "nums": [
            5,
            3,
            1,
            2,
            4,
            2,
            1
        ],
        "list":[
            {
                "name": "栖海澐颂",
                value: 5
            }
        ]

echarts安装

cnpm install echarts@4.9.0 --save

前端代码 

drawLine(){chart().then(res => {// 基于准备好的dom,初始化echarts实例let myChart = this.$echarts.init(document.getElementById('myChart'))// 绘制图表myChart.setOption({color: ['#3398DB'],title: {text: '智慧社区住户量统计',subtext: '对比图',left: 'center'},tooltip: {trigger: 'axis',axisPointer: {type: 'shadow'}},xAxis: {data: res.data.names},yAxis: {},series: [{name: '住户量',type: 'bar',data: res.data.nums}],animationType: 'scale',animationEasing: 'elasticOut',animationDelay: function (idx) {return Math.random() * 200;}});let myChart2 = this.$echarts.init(document.getElementById('myChart2'))myChart2.setOption({title: {text: '智慧社区住户量统计',subtext: '占比图',left: 'center'},tooltip: {trigger: 'item',formatter: '{a} <br/>{b} : {c} ({d}%)'},visualMap: {show: false,min: 80,max: 600,inRange: {colorLightness: [0, 1]}},series: [{name: '住户量',type: 'pie',radius: '55%',center: ['50%', '50%'],data: res.data.list.sort(function (a, b) { return a.value - b.value; }),roseType: 'radius',itemStyle: {color: '#3398DB'},animationType: 'scale',animationEasing: 'elasticOut',animationDelay: function (idx) {return Math.random() * 200;}}]});});}

chartVO数据封装

@Data
public class ChartVO {private Integer value;private String name;
}

查看小区数据统计controller请求

     /*** 查看小区数据统计* @return*/@GetMapping("/chart")public Result chart(){Map map = this.inOutRecordService.chart();return Result.ok().put("data", map);}

查看小区数据统计service 

    @Autowiredprivate InOutRecordMapper inOutRecordMapper;@Overridepublic Map chart() {Map<String, List> map = new HashMap<>();List<String> names = new ArrayList<>();List<Integer> nums = new ArrayList<>();List<ChartVO> chartVOList = inOutRecordMapper.chart();List<ChartVO> list = new ArrayList<>();for(ChartVO chartVo: chartVOList){names.add(chartVo.getName());nums.add(chartVo.getValue());list.add(chartVo);}map.put("names",names);map.put("nums",nums);map.put("list",list);return map;}

 查看小区数据统计mapper

@Select("select count(*) value, c.community_name name from community c, person p where p.community_id=c.community_id group by c.community_id")List<ChartVO> chart();

界面

6、代码生成器

生成代码

生成entity、mapper、mapper.xml、service、serviceImpl、controller文件

package com.qcby.community;import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;import java.util.Arrays;
import java.util.List;public class Main {public static void main(String[] args) {AutoGenerator autoGenerator = new AutoGenerator();DataSourceConfig dataSourceConfig = new DataSourceConfig();dataSourceConfig.setDbType(DbType.MYSQL);dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");dataSourceConfig.setUsername("root");dataSourceConfig.setPassword("123456");dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/community?useUnicode=true&characterEncoding=UTF-8");autoGenerator.setDataSource(dataSourceConfig);GlobalConfig globalConfig = new GlobalConfig();globalConfig.setOpen(false);globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");globalConfig.setAuthor("admin");globalConfig.setServiceName("%sService");autoGenerator.setGlobalConfig(globalConfig);PackageConfig packageConfig = new PackageConfig();packageConfig.setParent("com.qcby.community");packageConfig.setEntity("entity");packageConfig.setMapper("mapper");packageConfig.setController("controller");packageConfig.setService("service");packageConfig.setServiceImpl("service.impl");autoGenerator.setPackageInfo(packageConfig);StrategyConfig strategyConfig = new StrategyConfig();strategyConfig.setEntityLombokModel(true);strategyConfig.setNaming(NamingStrategy.underline_to_camel);strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);strategyConfig.setInclude("community");TableFill tableFill1 = new TableFill("create_time", FieldFill.INSERT);List<TableFill> list = Arrays.asList(tableFill1);strategyConfig.setTableFillList(list);autoGenerator.setStrategy(strategyConfig);autoGenerator.execute();}
}

生成示例,以community为例

entity

package com.qcby.community.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import java.util.Date;import lombok.Data;
import lombok.EqualsAndHashCode;/*** <p>* * </p>** @author admin* @since 2024-03-26*/
@Data@EqualsAndHashCode(callSuper = false)public class Community implements Serializable {private static final long serialVersionUID=1L;@TableId(value = "community_id", type = IdType.AUTO)private Integer communityId;/*** 小区名称*/private String communityName;/*** 楼栋数量*/private Integer termCount;/*** 序号*/private Integer seq;/*** 创建人*/private String creater;/*** 创建时间*/@TableField(fill = FieldFill.INSERT)private Date createTime;/*** 经度*/private Float lng;/*** 维度*/private Float lat;}

mapper

package com.qcby.community.mapper;import com.qcby.community.entity.Community;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;/*** <p>*  Mapper 接口* </p>** @author admin* @since 2024-03-26*/
public interface CommunityMapper extends BaseMapper<Community> {}

mapper.xml

<?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.qcby.community.mapper.CommunityMapper"></mapper>

service

package com.qcby.community.service;import com.qcby.community.entity.Community;
import com.baomidou.mybatisplus.extension.service.IService;
import com.qcby.community.form.CommunityListForm;
import com.qcby.community.vo.PageVO;/*** <p>*  服务类* </p>** @author admin* @since 2024-03-26*/
public interface CommunityService extends IService<Community> {}

serviceImpl

package com.qcby.community.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qcby.community.entity.Community;
import com.qcby.community.form.CommunityListForm;
import com.qcby.community.mapper.CommunityMapper;
import com.qcby.community.mapper.PersonMapper;
import com.qcby.community.service.CommunityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcby.community.vo.CommunityVO;
import com.qcby.community.vo.PageVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;/*** <p>*  服务实现类* </p>** @author admin* @since 2024-03-26*/
@Service
public class CommunityServiceImpl extends ServiceImpl<CommunityMapper, Community> implements CommunityService {}

controller

package com.qcby.community.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.stereotype.Controller;/*** <p>*  前端控制器* </p>** @author admin* @since 2024-03-26*/
@Controller
@RequestMapping("//community")
public class CommunityController {}

7、返回封装结果Result

此系统所有的结果都是返回json格式,统一返回样式如下,因此进行返回结果集的统一封装

{
    "msg": "操作成功",
    "code": 200

    // 其它数据
}

代码如下:

package com.qcby.community.util;import java.util.HashMap;public class Result extends HashMap<String,Object> {public static Result ok(){Result result = new Result();result.put("code", 200);result.put("msg", "操作成功");return result;}public static Result error(String msg){Result result = new Result();result.put("code", 500);result.put("msg", msg);return result;}@Overridepublic Result put(String key, Object value) {super.put(key, value);return this;}
}

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

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

相关文章

WordPress PHP内存限制优化,WordPress性能优化,提升WordPress PHP内存,防止内存溢出

它发生在所有WordPress网站所有者和管理员最终&#xff1a;可怕的WordPress内存错误。当你正在为自己的网站添加新的内容或媒体时&#xff0c;突然弹出一条消息&#xff1a;“致命错误&#xff1a;允许的内存大小为xxxxxx字节。”刚刚发生了什么&#xff1f;为什么WordPress会内…

【Vue + keep-alive】路由缓存

一. 需求 列表页&#xff0c;n 条数据项可打开 n 个标签页&#xff0c;同时1条数据项的查看和编辑共用一个标签页。如下所示&#xff1a; 参考 // 主页面 // 解决因 路由缓存&#xff0c;导致 编辑后跳转到该页面 不能实时更新数据 onActivated(() > {getList() })二. 实现…

电压继电器SRMUVS-220VAC-2H2D 导轨安装 JOSEF约瑟

系列型号&#xff1a; SRMUVS-58VAC-2H欠电压监视继电器&#xff1b;SRMUVS-100VAC-2H欠电压监视继电器&#xff1b; SRMUVS-110VAC-2H欠电压监视继电器&#xff1b;SRMUVS-220VAC-2H欠电压监视继电器&#xff1b; SRMUVS-58VAC-2H2D欠电压监视继电器&#xff1b;SRMUVS-100…

Spark_SparkSql写入Oracle_Undefined function.....将长字符串写入Oracle中方法..

在使用Spark编写代码将读库处理然后写入Oracle中遇到了诸多小bug,很磨人。shit!! 实测1&#xff1a;TO_CLOB(a3) 代码样例 --这是一个sparksql写入hive的一个小逻辑&#xff0c;我脱敏了噻 SELECT a1, a2, TO_CLOB(a3) AS clob_data, TO_DATE(a4) AS time FROM table1 WHERE…

2014最新AIGC创作系统ChatGPT网站源码+AI绘画网站源码+GPT4-All联网搜索模型

一、文章前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持…

鸿蒙HarmonyOS开发实战:【分布式音乐播放】

介绍 本示例使用fileIo获取指定音频文件&#xff0c;并通过AudioPlayer完成了音乐的播放完成了基本的音乐播放、暂停、上一曲、下一曲功能&#xff1b;并使用DeviceManager完成了分布式设备列表的显示和分布式能力完成了音乐播放状态的跨设备分享。 本示例用到了与用户进行交…

二:深入理解 JAVA 内存模型 JMM

目录 1、为什么要有内存模型1.1、为什么要有多级缓存&#xff1f;1.2、缓存一致性问题1.3、处理器优化和指令重排 2、并发编程的三大问题2.1、原子性问题2.2、有序性问题2.3、可见性问题2.4、三大特性 3、什么是内存模型&#xff1f;3.1、概念3.2、内存模型到底是怎么保证缓存一…

【Qt】:对话框(一)

对话框 一.基本的对话框二.自定义对话框三.通过图形化界面自定义对话框四.关于对话框mode 对话框是GUI程序中不可或缺的组成部分。一些不适合在主窗口实现的功能组件可以设置在对话框中。对话框通常是一个顶层窗口&#xff0c;出现在程序最上层&#xff0c;用于实现短期任务或者…

小程序项目思路分享爬虫

小程序项目思路分享爬虫 具体需求&#xff1a; 有这几个就行&#xff0c;门店名称门店地址门店类型&#xff0c;再加上省、市、县/区门店名称&#xff1a;storeName 门店地址&#xff1a;storeAddress 程序运行&#xff1a; honor_spider获取经纬度信息。 经纬度——>详…

CentOS上使用cgroup限制进程使用内存

安装cgroup 要使用cgroup首先需要系统支持&#xff0c;需要安装两个rpm包 yum install libcgroup libcgroup-tools 创建限制内存的cgroup组 cgroup组需要在/sys/fs/cgroup/memory目录下创建&#xff0c;我们创建一个限制进程内存大小为10M的cgroup组&#xff0c;这个组中内存…

云计算重要概念之:虚拟机、网卡、交换机、路由器、防火墙

一、虚拟机 (Virtual Machine, VM) 1.主流的虚拟化软件&#xff1a; 虚拟化软件通过在单个物理硬件上创建和管理多个虚拟环境&#xff08;虚拟机&#xff09;&#xff0c;实现资源的高效利用、灵活部署、隔离安全以及便捷管理&#xff0c;是构建云计算和现代化数据中心的核心…

【Linux】初识Linux,虚拟机安装Linux系统,配置网卡

前言 VMware软件&#xff1a;首先&#xff0c;确保您已经下载了VMware Workstation软件并安装在电脑上。VMware Workstation是一款功能强大的虚拟化软件&#xff0c;它允许在单一物理机上运行多个操作系统。 Linux镜像文件&#xff1a;需要准备一个Linux操作系统的镜像文件。…

华为ensp中PPP(点对点协议)中的PAP认证 原理和配置命令

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月8日14点31分 PPP协议&#xff08;Point-to-Point Protocol&#xff09;是点到点协议&#xff0c;是一种常用的串行链路层协议&#xff0c;用于在两个节点之间建立点…

如何保证消息不丢失?——使用rabbitmq的死信队列!

如何保证消息不丢失?——使用rabbitmq的死信队列&#xff01; 1、什么是死信 在 RabbitMQ 中充当主角的就是消息&#xff0c;在不同场景下&#xff0c;消息会有不同地表现。 死信就是消息在特定场景下的一种表现形式&#xff0c;这些场景包括&#xff1a; 消息被拒绝访问&am…

全国水科技大会 免费征集《水环境治理减污降碳协同增效示范案例》

申报时间截止到2024年4月15日&#xff0c;请各单位抓紧申报&#xff0c;申报条件及申报表请联系&#xff1a;13718793867 围绕水环境治理减污降碳协同增效领域&#xff0c;以资源化、生态化和可持续化为导向&#xff0c;面向生态、流城、城市、农村、工业园区、电力、石化、钢…

前端mock数据——使用mockjs进行mock数据

前端mock数据——使用mockjs进行mock数据 一、安装二、mockjs的具体使用 一、安装 首选需要有nodejs环境安装mockjs&#xff1a;npm install mockjs 若出现像上图这样的错&#xff0c;则只需npm install mockjs --legacy-peer-deps即可 src下新建mock文件夹&#xff1a; mo…

基于Java SpringBoot+Vue的体育用品库存管理系统

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

LeetCode | 数组 | 二分查找 | 35.搜索插入位置【C++】

题目链接 题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出…

C++ 线程库(thread)与锁(mutex)

一.线程库(thread) 1.1 线程类的简单介绍 thread类文档介绍 在C11之前&#xff0c;涉及到多线程问题&#xff0c;都是和平台相关的&#xff0c;比如windows和linux下各有自己的接口&#xff0c;这使得代码的可移植性比较差。C11中最重要的特性就是对线程进行支持了&#xff…

eNSP-抓包解析TCP三次握手和四次挥手的过程

一、环境搭建 1.设备连接 并 启动所有设备 2.服务器配置 3.客服端配置 二、抓包测试 1.打开抓包软件 2.客户端获取数据 三、抓包结果