actitivi自定义属性(二)

声明:此处activiti版本为6.0

此文章介绍后端自定义属性解析,前端添加自定义属性方法连接:activiti自定义属性(一)_ruoyi activiti自定义标题-CSDN博客

1、涉及到的类如下:

简介:DefaultXmlParser :xml自定义属性解析类 :实现解析指定节点下扩展字段xml节点

CustomBpmnJsonConverter:用于转换BPMN与JSON供activiti解析界面属性并应用,在ActivitiConfig中引入使用

CustomBpmnXmlConverter:用于xml与BPMN转换

CustomUserTaskJsonConverter:用户节点自定义扩展属性解析(xml与json互转)

CustomUserTaskXmlConverter:用户节点自定义扩展属性解析xml

ActivitiConfig:springboot整合activiti配置类

代码如下:

DefaultXmlParser :

import org.activiti.bpmn.converter.child.BaseChildElementParser;
import org.activiti.bpmn.model.*;import javax.xml.stream.XMLStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** xml自定义属性解析类 :实现解析指定节点下扩展字段xml节点**/
public class DefaultXmlParser extends BaseChildElementParser {//元素名称private String elementName;public DefaultXmlParser() {}public DefaultXmlParser(String elementName) {this.elementName = elementName;}public String getElementName() {return elementName;}/*** 解析指定节点下扩展字段xml节点* @param xtr               xml字节流读取器* @param parentElement     父节点对象* @param model             流程图模型对象* @throws Exception*/public void parseChildElement(XMLStreamReader xtr, BaseElement parentElement, BpmnModel model) throws Exception {Map<String, List<ExtensionElement>> map = parentElement.getExtensionElements();List<ExtensionElement> extensionElementList = new ArrayList<>();ExtensionElement extensionElement = new ExtensionElement();extensionElement.setName(getElementName());extensionElement.setElementText(xtr.getElementText());extensionElement.setNamespacePrefix("activiti");extensionElement.setNamespace("http://activiti.org/bpmn");extensionElementList.add(extensionElement);map.put(getElementName(), extensionElementList);}
}

CustomBpmnJsonConverter:

import org.activiti.bpmn.model.BaseElement;
import org.activiti.editor.language.json.converter.BaseBpmnJsonConverter;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;import java.util.Map;/*** 自定义bpmn解析,用于转换BPMN与JSON供activiti解析界面属性并应用**/
public class CustomBpmnJsonConverter extends BpmnJsonConverter {/*** 获取bpmn组件解析map* @return*/public static Map<String,Class<? extends BaseBpmnJsonConverter>> getConvertersToBpmnMap(){return convertersToBpmnMap;}/*** 获取bpmn组件解析map* @return*/public static Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>>  getConvertersToJsonMap(){return convertersToJsonMap;}}

CustomBpmnXmlConverter:

import org.activiti.bpmn.converter.BpmnXMLConverter;/*** 自定义bpmn解析,用于xml转换成BPMN**/
public class CustomBpmnXmlConverter extends BpmnXMLConverter {static {// 添加自定义用户节点xml解析器addConverter(new CustomUserTaskXmlConverter());}
}

CustomUserTaskJsonConverter:用户节点自定义扩展属性解析(xml与json互转)

用到的常量为自定义属性名

import com.self.common.constant.activiti.ActivitiNodeConstant;
import com.self.common.utils.StringUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.bpmn.model.*;
import org.activiti.editor.language.json.converter.BaseBpmnJsonConverter;
import org.activiti.editor.language.json.converter.UserTaskJsonConverter;import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** 用户节点自定义扩展属性解析(xml与json互转)*/
public class CustomUserTaskJsonConverter extends UserTaskJsonConverter {/*** xml => json* 将 xml格式的模型数据解析出来放入到节点的json自定义扩展属性中** @param propertiesNode* @param baseElement*/@Overrideprotected void convertElementToJson(ObjectNode propertiesNode, BaseElement baseElement) {super.convertElementToJson(propertiesNode, baseElement);//获取扩展属性并进行设置UserTask userTask = (UserTask) baseElement;Map<String, List<ExtensionElement>> map = userTask.getExtensionElements();for(String key : map.keySet()){List<ExtensionElement> extensionElementList = map.get(key);if (extensionElementList != null && extensionElementList.size() > 0) {propertiesNode.put(extensionElementList.get(0).getName(), extensionElementList.get(0).getElementText());}}}/*** json => xml* 将 json格式的模型数据解析出来放入到节点的自定义扩展属性中** @param elementNode* @param modelNode* @param shapeMap* @return*/@Overrideprotected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode, Map<String, JsonNode> shapeMap) {FlowElement flowElement = super.convertJsonToElement(elementNode, modelNode, shapeMap);//解析UserTask userTask = (UserTask) flowElement;List<CustomProperty> cpList = new ArrayList<>();//是否为并行节点,常量为自定义属性名handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_PARALLEL);//是否可以AA跳handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK);//节点审批人为空是否跳过handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_APPROVAL_NULL_SKIP_TASK);//跳过节点时意见handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK_OPINION);//是否可以修改表单handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_ACTMODIFY_FROM);//附件是否必填handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_FILE_REQUIRED);//是否可以查看流转记录handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_RECORD);//是否可配置审批记录查看权限handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_RECORD_PERMISSIONS);//抄送用户handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_CC_USERS);//是否显示流程图handleCustomProperties(cpList, elementNode, ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_PNG);userTask.setCustomProperties(cpList);return userTask;}public static void fillTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap,Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {fillJsonTypes(convertersToBpmnMap);fillBpmnTypes(convertersToJsonMap);}public static void fillJsonTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap) {convertersToBpmnMap.put(STENCIL_TASK_USER, CustomUserTaskJsonConverter.class);}public static void fillBpmnTypes(Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {convertersToJsonMap.put(UserTask.class, CustomUserTaskJsonConverter.class);}/*** 处理自定义属性** @param cpList      自定义属性列表* @param elementNode 任务节点* @param key         自定义属性key*/private void handleCustomProperties(List<CustomProperty> cpList, JsonNode elementNode, String key) {String value = getPropertyValueAsString(key, elementNode);if (StringUtils.isNotBlank(value)) {CustomProperty cp = new CustomProperty();cp.setName(key);cp.setSimpleValue(value);cpList.add(cp);}}}

CustomUserTaskXmlConverter:用户节点自定义扩展属性解析xml

用到的常量为自定义属性名

import com.self.activiti.config.extension.DefaultXmlParser;
import com.self.common.constant.activiti.ActivitiNodeConstant;
import org.activiti.bpmn.converter.UserTaskXMLConverter;/*** 用户节点自定义扩展属性解析xml*/
public class CustomUserTaskXmlConverter extends UserTaskXMLConverter {public CustomUserTaskXmlConverter() {super();//是否为并行节点childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_PARALLEL, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_PARALLEL));//是否可以AA跳childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK));//节点审批人为空是否跳过childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_APPROVAL_NULL_SKIP_TASK, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_APPROVAL_NULL_SKIP_TASK));//跳过节点时意见childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK_OPINION, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_SKIP_TASK_OPINION));//是否可以修改表单childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACTMODIFY_FROM, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACTMODIFY_FROM));//附件是否必填childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_FILE_REQUIRED, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_FILE_REQUIRED));//是否可以查看流转记录childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_RECORD, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_RECORD));//是否可配置审批记录查看权限childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_RECORD_PERMISSIONS, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_RECORD_PERMISSIONS));//抄送用户childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_CC_USERS, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_CC_USERS));//是否显示流程图childParserMap.put(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_PNG, new DefaultXmlParser(ActivitiNodeConstant.CUSTOM_PROPERTIES_ACT_APPROVAL_PNG));}
}

ActivitiConfig:

重点在于下面这句:

import com.self.activiti.id.MyIdGenerator;
import org.activiti.engine.*;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;/*** acitiviti配置类*/
@Configuration
public class ActivitiConfig  {@Autowiredprivate DataSource dataSource;@Autowiredprivate PlatformTransactionManager transactionManager;//流程配置,与spring整合采用SpringProcessEngineConfiguration这个实现@Beanpublic SpringProcessEngineConfiguration processEngineConfiguration(){SpringProcessEngineConfiguration processEngineConfiguration = new SpringProcessEngineConfiguration();processEngineConfiguration.setDataSource(dataSource);processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_TRUE);processEngineConfiguration.setDatabaseType(ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL);processEngineConfiguration.setIdGenerator(new MyIdGenerator());processEngineConfiguration.setTransactionManager(transactionManager);processEngineConfiguration.setJobManager(new MyJobManager());//自定义任务管理// 将自定义用户任务组件bpmn解析替换activiti中用户任务组件默认解析CustomUserTaskJsonConverter.fillTypes(CustomBpmnJsonConverter.getConvertersToBpmnMap(), CustomBpmnJsonConverter.getConvertersToJsonMap());//        processEngineConfiguration.setJobExecutorActivate(true);//JobExecutor是管理几个线程计时器的组成部分,JobExecutor对多线程的处理较为笨重缓慢
//        processEngineConfiguration.setAsyncExecutorEnabled(true);//定义为true,使用AsyncExecutor代替默认的JobExecutor;processEngineConfiguration.setAsyncExecutorActivate(true);//定义为true,工作流引擎在启动时就建立启动AsyncExecutor线程//流程图字体processEngineConfiguration.setActivityFontName("宋体");processEngineConfiguration.setAnnotationFontName("宋体");processEngineConfiguration.setLabelFontName("宋体");return processEngineConfiguration;}//流程引擎,与spring整合使用factoryBean@Beanpublic ProcessEngineFactoryBean processEngine(ProcessEngineConfiguration processEngineConfiguration){ProcessEngineFactoryBean processEngineFactoryBean = new ProcessEngineFactoryBean();processEngineFactoryBean.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);((ProcessEngineConfigurationImpl) processEngineConfiguration).setIdGenerator(new MyIdGenerator());return processEngineFactoryBean;}//八大接口@Beanpublic RepositoryService repositoryService(ProcessEngine processEngine){return processEngine.getRepositoryService();}@Beanpublic RuntimeService runtimeService(ProcessEngine processEngine){return processEngine.getRuntimeService();}@Beanpublic TaskService taskService(ProcessEngine processEngine){return processEngine.getTaskService();}@Beanpublic HistoryService historyService(ProcessEngine processEngine){return processEngine.getHistoryService();}@Beanpublic FormService formService(ProcessEngine processEngine){return processEngine.getFormService();}@Beanpublic IdentityService identityService(ProcessEngine processEngine){return processEngine.getIdentityService();}@Beanpublic ManagementService managementService(ProcessEngine processEngine){return processEngine.getManagementService();}@Beanpublic DynamicBpmnService dynamicBpmnService(ProcessEngine processEngine){return processEngine.getDynamicBpmnService();}}

ActivitiNodeConstant:常量表

/*** activiti节点类型常量表**/
public class ActivitiNodeConstant {//会签节点名称后缀public static final String NODE_NAME_COUNTERSIGN_SUFFIX = "-会签";//流程节点类型 -- 互斥网关public static final String NODE_NAME_EXCLUSIVE_GATEWAY = "exclusiveGateway";//流程节点类型 -- 并行网关public static final String NODE_NAME_PARALLEL_GATEWAY = "parallelGateway";//流程节点类型 -- 包容网关public static final String NODE_NAME_INCLUSIVE_GATEWAY = "inclusiveGateway";//流程节点类型 -- 开始事件public static final String NODE_NAME_START_EVENT = "startEvent";//流程节点类型 -- 结束事件public static final String NODE_NAME_END_EVENT = "endEvent";//流程节点类型 -- 边界事件public static final String NODE_NAME_BOUNDARY_EVENT = "boundaryEvent";//流程节点类型 -- 用户任务public static final String NODE_NAME_USER_TASK = "userTask";//流程节点类型 -- 服务任务public static final String NODE_NAME_SERVICE_TASK = "serviceTask";//节点自定义属性 -- 是否为并行节点public static final String CUSTOM_PROPERTIES_PARALLEL = "isparallel";//节点自定义属性 -- 是否可以AA跳public static final String CUSTOM_PROPERTIES_SKIP_TASK = "skiptask";//节点自定义属性 -- 节点审批人为空是否跳过public static final String CUSTOM_PROPERTIES_APPROVAL_NULL_SKIP_TASK = "approvalnullskiptask";//节点自定义属性 -- 跳过节点时意见public static final String CUSTOM_PROPERTIES_SKIP_TASK_OPINION = "skiptaskopinion";//节点自定义属性 -- 是否可以修改表单public static final String CUSTOM_PROPERTIES_ACTMODIFY_FROM = "actmodifyfrom";//节点自定义属性 -- 附件是否必填public static final String CUSTOM_PROPERTIES_FILE_REQUIRED = "filerequired";//节点自定义属性 -- 是否可以查看流转记录public static final String CUSTOM_PROPERTIES_ACT_APPROVAL_RECORD = "actapprovalrecord";//节点自定义属性 -- 是否可配置审批记录查看权限public static final String CUSTOM_PROPERTIES_ACT_RECORD_PERMISSIONS = "actrecordpermissions";//节点自定义属性 -- 抄送用户public static final String CUSTOM_PROPERTIES_CC_USERS = "ccusers";//节点自定义属性 -- 是否显示流程图public static final String CUSTOM_PROPERTIES_ACT_APPROVAL_PNG = "actapprovalpng";}

使用方法:

1、读取xml文件,转为bpmnModel

private BpmnModel inputStream2Xml(InputStream inputStream) throws Exception {//读取xml文件XMLInputFactory factory = XMLInputFactory.newInstance();XMLStreamReader reader = factory.createXMLStreamReader(new InputStreamReader(inputStream, "UTF-8"));BpmnModel bpmnModel = new CustomBpmnXmlConverter().convertToBpmnModel(reader);// bpmnModel转jsonBpmnJsonConverter converter = new BpmnJsonConverter();converter.convertToJson(bpmnModel);return bpmnModel;}

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

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

相关文章

在 JavaScript 中导入和导出 Excel XLSX 文件:SpreadJS

在 JavaScript 中导入和导出 Excel XLSX 文件 2023 年 12 月 5 日 使用 MESCIUS 的 SpreadJS 将完整的 JavaScript 电子表格添加到您的企业应用程序中。 SpreadJS 是一个完整的企业 JavaScript 电子表格解决方案&#xff0c;用于创建财务报告和仪表板、预算和预测模型、科学、工…

图的搜索(一):广度优先搜索算法和深度优先搜索算法

图的搜索&#xff08;一&#xff09;&#xff1a;广度优先搜索算法和深度优先搜索算法 本章主要记录了图的搜索算法&#xff0c;和可以解决图的基本问题——最短路径问题的算法。本章主要对图搜索的相关算法进行了介绍&#xff1a;广度优先搜索算法、深度优先搜索算法。 下一…

公网域名如何解析到内网IP服务器——快解析域名映射外网访问

在本地搭建主机应用后&#xff0c;由于没有公网IP或没有公网路由权限&#xff0c;在需要发布互联网时&#xff0c;就需要用到外网访问内网的一些方案。由于内网IP在外网不能直接访问&#xff0c;通常就用通过外网域名来访问内网的方法。那么&#xff0c;公网域名如何解析到内网…

权威认证!景联文科技入选杭州市2023年第二批省级“专精特新”中小企业认定名单

为深入贯彻党中央国务院和省委省政府培育专精特新的决策部署&#xff0c;10月7日&#xff0c;杭州市经济和信息化委员会公示了2023年杭州“专精特新”企业名单&#xff08;第二批&#xff09;。 根据工业和信息化部《优质中小企业梯度培育管理暂行办法》&#xff08;工信部企业…

【Vue3+Ts项目】硅谷甄选 — 路由配置+登录模块+layout组件+路由鉴权

一、路由配置 项目一共需要4个一级路由&#xff1a;登录&#xff08;login&#xff09;、主页&#xff08;home&#xff09;、404、任意路由&#xff08;重定向到404&#xff09;。 1.1 安装路由插件 pnpm install vue-router 1.2 创建路由组件 在src目录下新建views文件…

Graphpad Prism10.1.0 安装教程 (含Win/Mac版)

GraphPad Prism GraphPad Prism是一款非常专业强大的科研医学生物数据处理绘图软件&#xff0c;它可以将科学图形、综合曲线拟合&#xff08;非线性回归&#xff09;、可理解的统计数据、数据组织结合在一起&#xff0c;除了最基本的数据统计分析外&#xff0c;还能自动生成统…

Python:核心知识点整理大全8-笔记

目录 ​编辑 4.5 元组 4.5.1 定义元组 dimensions.py 4.5.2 遍历元组中的所有值 4.5.3 修改元组变量 4.6 设置代码格式 4.6.1 格式设置指南 4.6.2 缩进 4.6.3 行长 4.6.4 空行 4.6.5 其他格式设置指南 4.7 小结 第5章 if语句 5.1 一个简单示例 cars.py 5.2 条…

现代皮质沙发模型材质编辑

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 当谈到游戏角色的3D模型风格时&#xff0c;有几种不同的风格&#xf…

线性容器(QByteArray、QString、QList模板类)、堆栈窗体

QT 线性容器 点击查看&#xff1a;字符和字节的区别&#xff0c;ASCII、Unicode 和 UTF-8 编码的区别。&#xff08;&#x1f448; 安全链接&#xff0c;放心跳转&#xff09; QByteArray 思考&#xff1a;char buf[6] “hello”; 如果 C 语言中要利用 buf 内容重新生成 “…

学生备考使用台灯到底好不好?公认好用的护眼台灯推荐

在现代生活中&#xff0c;许多学生的学习压力越来越大&#xff0c;面临的近视几率也越来越大&#xff0c;特别是初中生&#xff0c;眼睛发育还未完全&#xff0c;使用不恰当的灯光也会对眼睛造成损害&#xff0c;特别是护眼台灯。虽然护眼台灯在功能上能够提供充足、柔和的光线…

《文存阅刊》期刊发表简介

《文存阅刊》以“深研文化创新&#xff0c;崇尚科学真理&#xff0c;坚持双百方针&#xff0c;打造学术精品”为办刊宗旨&#xff0c;涵盖艺术、文学、社科等多项内容&#xff0c;适应了文化市场需求&#xff0c;很好的回应了广大文化理论工作者的关切&#xff0c;为下一步打造…

ChatGPT新媒体运营神器:轻松驾驭内容创作与传播

文章目录 1. 内容创作2. 社交媒体管理3. 用户互动与客户服务 《巧用ChatGPT轻松玩转新媒体运营》内容简介作者简介目录前言/序言本书内容本书特色本书读者对象获取方式 随着互联网的高速发展&#xff0c;新媒体已经成为了人们获取信息、交流思想的重要渠道。在这个信息爆炸的时…

【SpringCache】快速入门 通俗易懂

1. 介绍 Spring Cache 是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;只需要简单地加一个注解&#xff0c;就能实现缓存功能。 Spring Cache 提供了一层抽象&#xff0c;底层可以切换不同的缓存实现&#xff0c;例如&#xff1a; EHCache Caffeine Redis(常用…

Centos7、Mysql8.0 load_file函数返回为空的终极解决方法--暨selinux的深入理解

零、问题背景 最近想换房&#xff0c;为了方便自己对比感兴趣的房子&#xff0c;因此决定将目标房源的基本信息放在表里&#xff0c;特别是要一目了然的看到众多房子的各种图纸和照片&#xff0c;因此决定要在Mysql8.0.34数据库中以二进制形式保存图片&#xff08;抛开合理性和…

Vue 2.0源码分析-update

Vue 的 _update 是实例的一个私有方法&#xff0c;它被调用的时机有 2 个&#xff0c;一个是首次渲染&#xff0c;一个是数据更新的时候&#xff1b;由于我们这一章节只分析首次渲染部分&#xff0c;数据更新部分会在之后分析响应式原理的时候涉及。_update 方法的作用是把 VNo…

思维链(CoT)提出者 Jason Wei:关于大语言模型的六个直觉

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 Jason Wei 的主页&#xff1a;https://www.jasonwei.net/ Jason Wei&#xff0c;一位于 2020 年从达特茅斯学院毕业的杰出青年&#xff0c;随后加盟了…

大数据安全保障的四种关键技术

随着大数据时代的到来&#xff0c;数据安全保障的重要性日益凸显。大数据安全保障涉及多种关键技术&#xff0c;以下是四种关键技术的详细介绍。 数据加密技术 数据加密技术是大数据安全保障的核心技术之一。它通过将明文数据转化为密文数据&#xff0c;以保护数据的机密性和完…

CSS中 设置文字下划线 的几种方法

在网页设计和开发中&#xff0c;我们经常需要对文字进行样式设置&#xff0c;包括字体,颜色&#xff0c;大小等&#xff0c;其中&#xff0c;设置文字下划线是一种常见需求 一 、CSS种使用 text-decoration 属性来设置文字的装饰效果&#xff0c;包括下划线。 常用的取值&…

炫酷不止一面:探索JavaScript动画的奇妙世界(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

proftpd安全加固:限制用户FTP登录

其实无所谓安全加固&#xff0c;因为proftp默认就是限制用户FTP登录的&#xff0c;这里有点凌乱得研究和实验了proftpd如何进行限制的&#xff0c;以及可能的放开限制。懂了这些才能更好的进行防护配置。 RootLogin指令其实主要作用就是启用ROOT访问。通常&#xff0c;proftpd在…