PageDTO<T>,PageQuery,BeanUtils,CollUtils的封装

一、PageDTO<T>

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.Convert;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "分页结果")
public class PageDTO<T> {
    @ApiModelProperty("总条数")
    protected Long total;
    @ApiModelProperty("总页码数")
    protected Long pages;
    @ApiModelProperty("当前页数据")
    protected List<T> list;

    public static <T> PageDTO<T> empty(Long total, Long pages) {
        return new PageDTO<>(total, pages, CollUtils.emptyList());
    }
    public static <T> PageDTO<T> empty(Page<?> page) {
        return new PageDTO<>(page.getTotal(), page.getPages(), CollUtils.emptyList());
    }

    public static <T> PageDTO<T> of(Page<T> page) {
        if(page == null){
            return new PageDTO<>();
        }
        if (CollUtils.isEmpty(page.getRecords())) {
            return empty(page);
        }
        return new PageDTO<>(page.getTotal(), page.getPages(), page.getRecords());
    }
    public static <T,R> PageDTO<T> of(Page<R> page, Function<R, T> mapper) {
        if(page == null){
            return new PageDTO<>();
        }
        if (CollUtils.isEmpty(page.getRecords())) {
            return empty(page);
        }
        return new PageDTO<>(page.getTotal(), page.getPages(),
                page.getRecords().stream().map(mapper).collect(Collectors.toList()));
    }
    public static <T> PageDTO<T> of(Page<?> page, List<T> list) {
        return new PageDTO<>(page.getTotal(), page.getPages(), list);
    }

    public static <T, R> PageDTO<T> of(Page<R> page, Class<T> clazz) {
        return new PageDTO<>(page.getTotal(), page.getPages(), BeanUtils.copyList(page.getRecords(), clazz));
    }

    public static <T, R> PageDTO<T> of(Page<R> page, Class<T> clazz, Convert<R, T> convert) {
        return new PageDTO<>(page.getTotal(), page.getPages(), BeanUtils.copyList(page.getRecords(), clazz, convert));
    }

    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public boolean isEmpty(){
        return list == null || list.size() == 0;
    }
}

二、 PageQuery

2.1 PageQuery代码

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxx.common.constants.Constant;
import com.xxx.common.utils.StringUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;

import javax.validation.constraints.Min;

@Data
@ApiModel(description = "分页请求参数")
@Accessors(chain = true)
public class PageQuery {
    public static final Integer DEFAULT_PAGE_SIZE = 20;
    public static final Integer DEFAULT_PAGE_NUM = 1;

    @ApiModelProperty(value = "页码", example = "1")
    @Min(value = 1, message = "页码不能小于1")
    private Integer pageNo = DEFAULT_PAGE_NUM;

    @ApiModelProperty(value = "每页大小", example = "5")
    @Min(value = 1, message = "每页查询数量不能小于1")
    private Integer pageSize = DEFAULT_PAGE_SIZE;

    @ApiModelProperty(value = "是否升序", example = "true")
    private Boolean isAsc = true;

    @ApiModelProperty(value = "排序字段", example = "id")
    private String sortBy;

    public int from(){
        return (pageNo - 1) * pageSize;
    }

    public <T> Page<T> toMpPage(OrderItem ... orderItems) {
        Page<T> page = new Page<>(pageNo, pageSize);
        // 是否手动指定排序方式
        if (orderItems != null && orderItems.length > 0) {
            for (OrderItem orderItem : orderItems) {
                page.addOrder(orderItem);
            }
            return page;
        }
        // 前端是否有排序字段
        if (StringUtils.isNotEmpty(sortBy)){
            OrderItem orderItem = new OrderItem();
            orderItem.setAsc(isAsc);
            orderItem.setColumn(sortBy);
            page.addOrder(orderItem);
        }
        return page;
    }

    public <T> Page<T> toMpPage(String defaultSortBy, boolean isAsc) {
        if (StringUtils.isBlank(sortBy)){
            sortBy = defaultSortBy;
            this.isAsc = isAsc;
        }
        Page<T> page = new Page<>(pageNo, pageSize);
        OrderItem orderItem = new OrderItem();
        orderItem.setAsc(this.isAsc);
        orderItem.setColumn(sortBy);
        page.addOrder(orderItem);
        return page;
    }
    public <T> Page<T> toMpPageDefaultSortByCreateTimeDesc() {
        return toMpPage(Constant.DATA_FIELD_NAME_CREATE_TIME, false);
    }
}

2.2 使用举例

@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(description = "互动问题分页查询条件")
public class QuestionPageQuery extends PageQuery {
    // 用户端查询条件
    @ApiModelProperty(value = "课程id")
    private Long courseId;
    @ApiModelProperty(value = "小节id", example = "1")
    private Long sectionId;
    @ApiModelProperty(value = "是否只查询我的问题", example = "1")
    private Boolean onlyMine;
}

----------------------------------------------------------------

//1 获取用户id
Long userId = UserContext.getUser();

Boolean onlyMine = query.getOnlyMine(); // 是否只查询自己
Long sectionId = query.getSectionId();
Long courseId = query.getCourseId();
//2 分页查询问题表(question)数据
// selecgt * from question  where user_id=?  and course_id =? and section_id=? and hidden= false;
Page<InteractionQuestion> page = this.lambdaQuery()
        .eq(onlyMine, InteractionQuestion::getUserId, userId) // 只查询自己,才拼接条件
        .eq(courseId != null, InteractionQuestion::getCourseId, courseId) // 传递了 课程,才拼接课程查询
        .eq(sectionId != null, InteractionQuestion::getSectionId, sectionId)  // 传递了 小节,才拼接小节查询
        .eq(InteractionQuestion::getHidden, false) // 被管理员隐藏的不显示
        .page(query.toMpPageDefaultSortByCreateTimeDesc()); // 按照创建日期倒叙排序
List<InteractionQuestion> records = page.getRecords();
if(CollUtils.isEmpty(records)){ // 如果没有
    return PageDTO.empty(page);
}
// 1.获取用户id
Long userId = UserContext.getUser();
// 2) 分页查询数据库
// select * from learning_lesson where user_id=?  order by create_time desc  limit 5

Page<LearningLesson> page = this.lambdaQuery()
        .eq(LearningLesson::getUserId, userId)
        .page(query.toMpPage("latest_learn_time", false));

//  mybatis  会把  查询的数据全部封装到 page 中: 数据, 总条数数据集
List<LearningLesson> records = page.getRecords(); // 获取当前页数据
if(CollUtils.isEmpty(records)){
    return PageDTO.empty(page); // 如果没有数据返回空对象
}

三、BeanUtils

3.1 BeanUtils代码

import cn.hutool.core.bean.BeanUtil;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 继承自 hutool 的BeanUtil,增加了bean转换时自定义转换器的功能
 */
public class BeanUtils extends BeanUtil {

    /**
     * 将原对象转换成目标对象,对于字段不匹配的字段可以使用转换器处理
     *
     * @param source  原对象
     * @param clazz   目标对象的class
     * @param convert 转换器
     * @param <R>     原对象类型
     * @param <T>     目标对象类型
     * @return 目标对象
     */
    public static <R, T> T copyBean(R source, Class<T> clazz, Convert<R, T> convert) {
        T target = copyBean(source, clazz);
        if (convert != null) {
            convert.convert(source, target);
        }
        return target;
    }
    /**
     * 将原对象转换成目标对象,对于字段不匹配的字段可以使用转换器处理
     *
     * @param source  原对象
     * @param clazz   目标对象的class
     * @param <R>     原对象类型
     * @param <T>     目标对象类型
     * @return 目标对象
     */
    public static <R, T> T copyBean(R source, Class<T> clazz){
        if (source == null) {
            return null;
        }
        return toBean(source, clazz);
    }

    public static <R, T> List<T> copyList(List<R> list, Class<T> clazz) {
        if (list == null || list.size() == 0) {
            return CollUtils.emptyList();
        }
        return copyToList(list, clazz);
    }

    public static <R, T> List<T> copyList(List<R> list, Class<T> clazz, Convert<R, T> convert) {
        if (list == null || list.size() == 0) {
            return CollUtils.emptyList();
        }
        return list.stream().map(r -> copyBean(r, clazz, convert)).collect(Collectors.toList());
    }
}
package com.xxx.common.utils;

/**
 * 对原对象进行计算,设置到目标对象中
 **/
public interface Convert<R,T>{
    void convert(R origin, T target);
}

3.2 举例

在这里插入图片描述

在这里插入图片描述

    public void save(CourseTeacherSaveDTO courseTeacherSaveDTO) {

        //1.数据删除条件
        LambdaUpdateWrapper<CourseTeacherDraft> updateWrapper =
                Wrappers.lambdaUpdate(CourseTeacherDraft.class)
                        .eq(CourseTeacherDraft::getCourseId, courseTeacherSaveDTO.getId());
        //1.1.数据删除
        baseMapper.delete(updateWrapper);

        //2.组装即将插入的数据
        // List<TeacherInfo> teachers
        List<CourseTeacherDraft> courseTeacherDrafts =
                BeanUtils.copyList(courseTeacherSaveDTO.getTeachers(),
                        CourseTeacherDraft.class,
                        (teacherInfo, teacherDraft) -> {
                            //2.1.设置课程id
                            teacherDraft.setCourseId(courseTeacherSaveDTO.getId());
                            //2.2.设置老师id
                            teacherDraft.setTeacherId(teacherInfo.getId());
                            //2.3.设置课程中老师排序
                            teacherDraft.setCIndex(courseTeacherSaveDTO.getTeachers().indexOf(teacherInfo));
                        });
        //3.批量插入课程的老师信息
        saveBatch(courseTeacherDrafts);
        //4.更新课程填写进度
        courseDraftService.updateStep(courseTeacherSaveDTO.getId(), CourseConstants.CourseStep.TEACHER);
    }

-----------------------------------------------------
@ApiModel("课程老师关系模型")
public class CourseTeacherSaveDTO {
    @ApiModelProperty("课程id")
    @NotNull(message = CourseErrorInfo.Msg.COURSE_TEACHER_SAVE_COURSE_ID_NULL)
    private Long id;
    @ApiModelProperty("老师id和用户端是否展示,该列表按照界面上的顺序")
    @NotNull(message = CourseErrorInfo.Msg.COURSE_TEACHER_SAVE_TEACHERS_NULL)
//    @Min(value = 1, message = CourseErrorInfo.Msg.COURSE_TEACHER_SAVE_TEACHERS_NULL)
    @Size(min = 1, max = 5, message = CourseErrorInfo.Msg.COURSE_TEACHER_SAVE_TEACHERS_NUM_MAX )
    private List<TeacherInfo> teachers;

    @Data
    @ApiModel("老师id和用户端是否显示")
    public static class TeacherInfo{
        @ApiModelProperty("老师id")
        @NotNull(message = CourseErrorInfo.Msg.COURSE_TEACHER_SAVE_TEACHER_ID_NULL)
        private Long id;
        @ApiModelProperty("用户端是否展示")
        @NotNull(message = CourseErrorInfo.Msg.COURSE_TEACHER_SAVE_TEACHER_SHOW)
        private Boolean isShow;
    }
}

四、CollUtils

4.1 CollUtils代码

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.IterUtil;
import com.xxx.common.validate.Checker;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 继承自 hutool 的集合工具类
 */
public class CollUtils extends CollectionUtil {

    public static <T> List<T> emptyList() {
        return Collections.emptyList();
    }

    public static <T> Set<T> emptySet() {
        return Collections.emptySet();
    }

    public static <K,V> Map<K, V> emptyMap() {
        return Collections.emptyMap();
    }

    public static <T> Set<T> singletonSet(T t) {
        return Collections.singleton(t);
    }

    public static <T> List<T> singletonList(T t) {
        return Collections.singletonList(t);
    }

    public static List<Integer> convertToInteger(List<String> originList){
        return CollUtils.isNotEmpty(originList) ? originList.stream().map(NumberUtils::parseInt).collect(Collectors.toList()) : null;
    }

    public static List<Long> convertToLong(List<String> originLIst){
        return CollUtils.isNotEmpty(originLIst) ? originLIst.stream().map(NumberUtils::parseLong).collect(Collectors.toList()) : null;
    }

    /**
     * 以 conjunction 为分隔符将集合转换为字符串 如果集合元素为数组、Iterable或Iterator,则递归组合其为字符串
     * @param collection 集合
     * @param conjunction 分隔符
     * @param <T> 集合元素类型
     * @return 连接后的字符串
     * See Also: IterUtil.join(Iterator, CharSequence)
     */
    public static <T> String join(Collection<T> collection, CharSequence conjunction) {
        if (null == collection || collection.isEmpty()) {
            return null;
        }
        return IterUtil.join(collection.iterator(), conjunction);
    }

    public static <T> String joinIgnoreNull(Collection<T> collection, CharSequence conjunction) {
        if (null == collection || collection.isEmpty()) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (T t : collection) {
            if(t == null) continue;
            sb.append(t).append(",");
        }
        if(sb.length() <= 0){
            return null;
        }
        return sb.deleteCharAt(sb.length() - 1).toString();
    }

    /**
     * 集合校验逻辑
     *
     * @param data 要校验的集合
     * @param checker 校验器
     * @param <T> 集合元素类型
     */
    public static  <T> void  check(List<T> data, Checker<T> checker){
        if(data == null){
            return;
        }
        for (T t : data){
            checker.check(t);
        }
    }

    /**
     * 集合校验逻辑
     *
     * @param data 要校验的集合
     * @param <T> 集合元素类型
     */
    public static  <T extends Checker<T>> void  check(List<T> data){
        if(data == null){
            return;
        }
        for (T t : data){
            t.check();
        }
    }

    /**
     * 将元素加入到集合中,为null的过滤掉
     *
     * @param list 集合
     * @param data 要添加的数据
     * @param <T> 元素类型
     */
    public static <T> void add(Collection<T> list, T... data) {
        if (list == null || ArrayUtils.isEmpty(data)) {
            return;
        }
        for (T t : data) {
            if (ObjectUtils.isNotEmpty(t)) {
                list.add(t);
            }
        }
    }
    //将两个集合出现次数相加
    public static Map<Long, Integer> union(Map<Long, Integer> map1, Map<Long, Integer> map2) {
        if (CollUtils.isEmpty(map1)) {
            return map2;
        } else if (CollUtils.isEmpty(map2)) {
            return map1;
        }
        for (Map.Entry<Long, Integer> entry : map1.entrySet()) {
            Integer num = map2.get(entry.getKey());
            map2.put(entry.getKey(), NumberUtils.null2Zero(num) + entry.getValue());
        }
        return map2;
    }

    public static <T,R> R getFiledOfFirst(List<T> list, Function<T, R> function) {
        if (CollUtils.isEmpty(list)) {
            return null;
        }
        return function.apply(list.get(0));
    }
}

/**
 * 实现后在接口访问时如果接口实现了这个接口
 * 会被自动自行接口check进行校验
 **/
public interface Checker<T> {

    /**
     * 用于实现validation不能校验的数据逻辑
     */
    default void check(){

    }

    default void check(T data){
    }
}

4.2 checker举例

@ApiModel(description = "章节")
public class CataSaveDTO implements Checker {
    @ApiModelProperty("章、节、练习id")
    private Long id;
    @ApiModelProperty("目录类型1:章,2:节,3:测试")
    @NotNull(message = "")
    private Integer type;
    @ApiModelProperty("章节练习名称")
    private String name;
    @ApiModelProperty("章排序,章一定要传,小节和练习不需要传")
    private Integer index;

    @ApiModelProperty("当前章的小节或练习")
    @Size(min = 1, message = "不能出现空章")
    private List<CataSaveDTO> sections;

    @Override
    public void check() {
        //名称为空校验
        if(type == CourseConstants.CataType.CHAPTER && StringUtils.isEmpty(name)) {
            throw new BadRequestException(CourseErrorInfo.Msg.COURSE_CATAS_SAVE_NAME_NULL);
        }else if(StringUtils.isEmpty(name)){
            throw new BadRequestException(CourseErrorInfo.Msg.COURSE_CATAS_SAVE_NAME_NULL2);
        }
        //名称长度问题
        if (type == CourseConstants.CataType.CHAPTER && name.length() > 30){
            throw new BadRequestException(CourseErrorInfo.Msg.COURSE_CATAS_SAVE_NAME_SIZE);
        }else if(name.length() > 30) {
            throw new BadRequestException(CourseErrorInfo.Msg.COURSE_CATAS_SAVE_NAME_SIZE2);
        }
        if(CollUtils.isEmpty(sections)){
            throw new BadRequestException("不能出现空章");
        }

    }
}
@ApiModel("题目保存模型")
@Data
public class SubjectSaveDTO implements Checker {
    @ApiModelProperty("题目id,为空新增,不为空更新")
    private Long id;
    @ApiModelProperty("名称")
    @NotNull(message = "题目为空,请设置题目")
    @Size(max = 200, min = 5, message = "题目长度为5-200")
    private String name;
    @ApiModelProperty("所属题目分类")
    @NotNull(message = "题目分类为空,请设置题目分类")
    private List<List<Long>> cates;
    @ApiModelProperty("题目类型")
    @NotNull(message = "题目类型为空,请设置题目类型")
    @EnumValid(enumeration = {1,2,3,4,5}, message = "题目类型只有单选题,多选题,不定向选择题,判断题,您的题目超出题纲")
    private Integer subjectType;
    @ApiModelProperty("题目难易度")
    @NotNull(message = "难度不能为空")
    @EnumValid(enumeration = {1,2,3},message = "题目难度只有简单,中等,困难")
    private Integer difficulty;
    @ApiModelProperty("分值")
    private Integer score;

    @ApiModelProperty("课程id")
    private List<Long> courseIds;

    @ApiModelProperty("选项,最多10个")
    private List<String> options;

    @ApiModelProperty("答案,判断题,数组第一个如果是1,代表正确,其他代表错误")
    @NotNull(message = "题目答案不能为空")
    private List<Integer> answers;
    @ApiModelProperty("解析")
    private String analysis;

    @Override
    public void check() {
        //选择题 单选,多选,不定向选择
        if(subjectType == SubjectConstants.Type.SIGNLE_CHOICE.getType() ||
                subjectType == SubjectConstants.Type.MUtiple_CHOICE.getType() ||
                subjectType == SubjectConstants.Type.NON_DIRECTIONAL_CHOICE.getType()){
            Integer answerOptionMax = answers.stream().max(Integer::compare).get();
            //选项最少1个最多10个
            if(CollUtils.isEmpty(options) || options.size() > 10){
                throw new BizIllegalException("最少1个选项,最多10个选项");
            }
            //选择题答案 不能超过选项数
            if(answerOptionMax > options.size()){
                throw new BizIllegalException("存在正确的答案找不到选项");
            }
            if(StringUtils.isNotEmpty(analysis)
                    && (StringUtils.length(analysis) < 5
                    || StringUtils.length(analysis) > 300)) {
                throw new BadRequestException("答案解析长度为5-300");
            }
        }

    }
}

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

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

相关文章

计算机网络——网络层(概念及IP地址划分)

目录 网络层概念 网络层向上层提供的两种服务 虚电路 网络提供数据报服务 虚电路服务与数据报服务的对比 网络层的两个层面 分组传送到路由器的运作 对网络层进行分层 网际协议IP 虚拟互联网络 IP地址 IP地址及其表示方法 IP地址的计算方式 IP地址的结构 …

【目标跟踪】CoTracker 环境配置

配置 CoTracker 环境 首先下载 conda&#xff0c;然后安装虚拟环境。 1.创建环境&#xff1a;如果环境不存在&#xff0c;你需要创建一个新的 conda 环境。可以使用以下命令创建名为 cotracker 的环境&#xff1a; conda create -n cotracker python3.x 其中 3.x 是你想要安…

欧姆龙安全PLC及周边产品要点指南

电气安全、自动化设备作业安全&#xff0c;向来是非常非常之重要的&#xff01;越来越多的客户在规划新产线、改造既有产线的过程中&#xff0c;明确要求设计方和施工方将安全考虑进整体方案中进行考虑和报价&#xff01;作为一名自动化电气工程师&#xff0c;尤其是高级工程师…

大话光学原理:4.散射:瑞利、拉曼、米氏和布里渊

这是一缕柔和的光&#xff0c;在空气的舞台上轻盈地跳跃。它悠然自得&#xff0c;在宁静的空间中缓缓前行。然而&#xff0c;一片细薄透明的介质挡住了它的脚步&#xff0c;它毫无预兆地撞上了这片障碍。在这短暂的接触中&#xff0c;它被分解成无数微小的粒子&#xff0c;被迫…

Python30 使用Gensim库实现Word2Vec对文本进行处理

1.Word2Vec Word2Vec 是一种将词语表示为向量的技术&#xff0c;能够捕捉词语之间的语义关系。它由 Google 的 Tomas Mikolov 等人在 2013 年提出&#xff0c;广泛应用于自然语言处理任务中。其核心概念主要包括&#xff1a; 词嵌入&#xff08;Word Embeddings&#xff09; …

【重大消息】报告称OpenAI的产品可经由微软的服务提供给中国客户

尽管OpenAI正在采取措施限制中国用户访问其平台&#xff0c;但一份最新报告称&#xff0c;中国用户仍可通过微软的Azure云计算平台访问该公司的产品。微软和OpenAI有着密切的合作关系&#xff0c;前者通过人工智能功能获得了独家产品访问权以拓展企业计算。最新的报道来自《The…

拓展神经网络八股(入门级)

自制数据集 minst等数据集是别人打包好的&#xff0c;如果是本领域的数据集。自制数据集。 替换 把图片路径和标签文件输入到函数里&#xff0c;并返回输入特征和标签 只需要把图片灰度值数据拼接到特征列表&#xff0c;标签添加到标签列表,提取操作函数如下&#xff1a; def…

25.无源蜂鸣器驱动设计

相对于有源蜂鸣器&#xff0c;无源蜂鸣器的成本更低&#xff0c;声音频率可控。而有源蜂鸣器因其内部 自带振荡源&#xff0c;只要加上适当的直流电源即可发声&#xff0c;程序控制较为方便。 &#xff08;1&#xff09;设计定义&#xff1a;设计一个无源蜂鸣器的驱动程序&…

基于泰坦尼克号生还数据进行 Spark 分析

基于泰坦尼克号生还数据进行 Spark 分析 在这篇博客中&#xff0c;我们将展示如何使用 Apache Spark 分析著名的泰坦尼克号数据集。通过这篇教程&#xff0c;您将学习如何处理数据、分析乘客的生还情况&#xff0c;并生成有价值的统计信息。 数据解析 • PassengerId &#…

ctfshow-web入门-文件上传(web164、web165)图片二次渲染绕过

web164 和 web165 的利用点都是二次渲染&#xff0c;一个是 png&#xff0c;一个是 jpg 目录 1、web164 2、web165 二次渲染&#xff1a; 网站服务器会对上传的图片进行二次处理&#xff0c;对文件内容进行替换更新&#xff0c;根据原有图片生成一个新的图片&#xff0c;这样…

EasyCVR视频汇聚平台:存储系统怎么选?分布式存储vs.集中式存储的区别在哪?

在当今的数字化时代&#xff0c;安防监控已成为维护社会秩序和公共安全的重要手段。随着监控设备的普及和监控数据的不断增加&#xff0c;如何高效、安全地存储和管理这些视频数据&#xff0c;成为了安防行业面临的重要挑战。EasyCVR视频存储系统凭借其卓越的性能和灵活的架构&…

综合安全防护

题目 1,DMZ区内的服务器,办公区仅能在办公时间内(9:00-18:00)可以访问,生产区的设备全天可以访问. 2,生产区不允许访问互联网,办公区和游客区允许访问互联网 3,办公区设备10.0.2.10不允许访问DMz区的FTP服务器和HTTP服务器,仅能ping通10.0.3.10 4,办公区分为市场部和研发部,研…

pnpm workspace使用教程【Monorepo项目】

目录 前言一、pnpm简介特点&#xff1a;对比 二、 创建项目添加文件 pnpm-workspace.yaml目录结构pnpm workspace: 协议修改配置文件执行 安装 三、命令解析执行包命令所有包操作命令 四、实例代码 前言 前面两篇&#xff0c;我们讲了 yarn workspace 和 lerna &#xff0c; …

局域网远程共享桌面如何实现

在局域网内实现远程共享桌面&#xff0c;可以通过以下几种方法&#xff1a; 一、使用Windows自带的远程桌面功能&#xff1a; 首先&#xff0c;在需要被控制的电脑上右键点击“此电脑”&#xff0c;选择“属性”。 进入计算机属性界面后&#xff0c;点击“高级系统设置”&am…

记录excel表生成一列按七天一个周期的方法

使用excel生成每七天一个周期的列。如下图所示&#xff1a; 针对第一列的生成办法&#xff0c;使用如下函数&#xff1a; TEXT(DATE(2024,1,1)(ROW()-2)*7,"yyyy/m/d")&" - "&TEXT(DATE(2024,1,1)(ROW()-1)*7-1,"yyyy/m/d") 特此记录。…

一文实践强化学习训练游戏ai--doom枪战游戏实践

一文实践强化学习训练游戏ai–doom枪战游戏实践 上次文章写道下载doom的环境并尝试了简单的操作&#xff0c;这次让我们来进行对象化和训练、验证&#xff0c;如果你有基础&#xff0c;可以直接阅读本文&#xff0c;不然请你先阅读Doom基础知识&#xff0c;其中包含了下载、动作…

android CameraX构建相机拍照

Android CameraX 是一个 Jetpack 支持库&#xff0c;旨在简化相机应用的开发工作。它提供了一致且易用的API接口&#xff0c;适用于大多数Android设备&#xff0c;并可向后兼容至Android 5.0&#xff08;API级别21&#xff09;。 CameraX解决了在多种设备上实现相机功能时所遇…

14-56 剑和诗人30 - IaC、PaC 和 OaC 在云成功中的作用

介绍 随着各大企业在 2024 年加速采用云计算&#xff0c;基础设施即代码 (IaC)、策略即代码 (PaC) 和优化即代码 (OaC) 已成为成功实现云迁移、IT 现代化和业务转型的关键功能。 让我在云计划的背景下全面了解这些代码功能的当前状态。我们将研究现代云基础设施趋势、IaC、Pa…

java:获取当前的日期和时间

// 获取当前的日期和时间LocalDateTime now LocalDateTime.now();// 定义日期时间格式化器DateTimeFormatter formatter DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");// 格式化日期时间String formattedDateTime now.format(formatter);// 打印结果Syste…

【数据结构和算法的概念等】

目录 一、数据结构1、数据结构的基本概念2、数据结构的三要素2.1 数据的逻辑结构2.2 数据的存储&#xff08;物理&#xff09;结构2.3 数据的运算 二、算法1、算法概念2、算法的特性及特点3、算法分析 一、数据结构 1、数据结构的基本概念 数据&#xff1a; 是所有能输入到计…