首页 文章 精选 留言 我的

精选列表

搜索[腾讯极客挑战赛],共10001篇文章
优秀的个人博客,低调大师

极简通讯 JSSDK 发布 - 轻松拥有通讯能力 🐒 WuKongIM

EasyJSSDK 一个简单易用的 WuKongIM 通讯 SDK,基于其 JSON-RPC 协议。(地址:https://gitee.com/WuKongDev/EasyJSSDK) WuKongIM 开源地址:https://gitee.com/WuKongDev/WuKongIM 安装 npm install easyjssdk 使用方法 // 引入必要的组件 import { WKIM, WKIMChannelType, WKIMEvent } from 'easyjssdk'; // 1. 初始化 const im = WKIM.init("ws://your-wukongim-server.com:5200", { uid: "your_user_id", // 你的用户 ID token: "your_auth_token" // 你的认证令牌 // deviceId: "optional_device_id", // 可选的设备 ID // deviceFlag: 2 // 可选的设备标识 (1:APP, 2:WEB, 默认为 2) }); // 2. 收消息 im.on(WKIMEvent.Message, (message) => { console.log("收到消息:", message); // 处理收到的消息 (message.payload, message.fromUid 等) }); // 3. 连接到服务器 im.connect() // 4. 示例:连接成功后发送一条消息 const targetUserId = "friend_user_id"; // 目标用户 ID const messagePayload = { type: 1, content: "来自 EasyJSSDK 的问候!" }; // 你的自定义消息负载 return im.send(targetUserId, WKIMChannelType.Person, messagePayload); 开发 克隆本仓库。 运行 npm install 安装依赖。 运行 npm run build 将 TypeScript 编译成 JavaScript。 运行示例程序 仓库中包含一个简单的 HTML/JS 示例用于测试 SDK。 构建 SDK: 确保你已经先构建了库文件: <pre> npm run build 启动本地服务器: 在你的终端中,导航到本项目的根目录 (EasyJSSDK)。你需要使用一个本地 Web 服务器来提供文件服务,因为示例使用了 ES Modules。一个简单的方法是使用 http-server: <pre> # 如果你还没有 http-server,请全局安装: npm install -g http-server 从 EasyJSSDK 目录运行服务器: http-server . 或者,使用 VS Code 的 "Live Server" 扩展或其他任何本地服务器,确保它从项目根目录 (<code>EasyJSSDK</code>) 提供服务。 </li> <li> <strong>打开示例:</strong> 打开你的 Web 浏览器并访问示例页面,通常是: <code>http://localhost:8080/example/</code> (如果你的服务器使用了不同的端口号,请相应调整)。 </li> <li> <strong>测试:</strong> 输入你的 WuKongIM 服务器信息 (URL, UID, Token),然后使用按钮进行连接、断开和发送消息的测试。 </li>

优秀的个人博客,低调大师

每日一博 | 极简 Java 工作流概念入门

关于 Flowable 松哥已经更新了好几篇文章了,不过考虑到有的小伙伴可能还从来没接触过流程引擎,因此有一些基础的内容我再来和小伙伴们梳理一下。 1. 为什么需要工作流 松哥将之前的文章转发到朋友圈后,有小伙伴评论说一直不理解为什么需要工作流,今天我们就先来说说这个话题。 假设我有一个请假需求,流程如下: 请假可以提交给我的上司,上司可以选择批准或者拒绝,无论批准还是拒绝,都会给我一个通知。 这个流程比较简单,我们很容易想到解决方案,不用工作流也能解决,有一个专门的请假表,当 A 要请假的时候,就往请假表中添加一条记录,这条记录的内容包含了请假的天数、原因、请假的审批人 B 以及一个名为 status 的字段,这个 status 字段表示这个请假申请目前的状态(待审批、已批准还是已拒绝),然后 B 登录系统之后,在请假表中查询到了 A 的请假信息,然后选择批准,此时将 status 字段的值改一下就行了。 这个流程很简单,相信小伙伴们都能想到。 然而,这是一个非常简单的流程,对于这样的流程,一般来说也确实没有必要使用工作流,但是现实中,我们涉及到的工作流往往都是非常复杂的,我举个例子,就说报销审批吧,这个可能很多小伙伴都经历过。 小伙伴们看到,这个流程相对来说还是比较复杂的,此时你再用一个 status 字段去描述,就很难说的请到底是怎么回事了。每一步审批,都有可能批准也有可能拒绝,拒绝并不意味着流程结束,员工修改报销资料之后,还可以继续提交。此时如果还用 status 去描述,那么 status 将有 N 多个值去表示不同的情况,这个维护起来非常不便。 这就复杂了吗?非也非也,我们再来看一个生产笔记本电脑的例子,假设公司研发了一款新型笔记本电脑,整个研发到生产的流程可能是这样: 相比上面两个,这个就更复杂一些了,不仅有串行任务还有并行任务,如何去设计这样一个系统?单纯的通过状态字段去描述显然已经不够用了,此时我们就得考虑一种通用的、更易维护的方案来实现这样的系统了,这种通用的、易维护的方案,也就是工作流。 2. 三大工作流 一个比较早的工作流是 jBPM,这是一个由 Java 实现的企业级流程引擎,是 JBoss 公司开发的产品之一。 jBPM 的创建者是 Tom Baeyens,这个大佬后来离开了 JBoss,并加入到 Alfresco,并推出了基于 jBPM4 的开源工作流系统 Activiti,而 jBPM 则在后续的代码中完全放弃了 jBPM4 的代码。从这个过程中也能看出来,jBPM 在发展过程中,由于意见相左,后来变成了两个 jBPM 和 Activiti。 然而戏剧的是,Activiti5 没搞多久,从 Activiti 中又分出来一个 Camunda,Activiti 继续发展,又从中分出来一个 Flowable。。。 由于开发 jBPM、Activiti、Camunda 以及 Flowable 的人多多少少有一些关联性,让人不得不猜测意见相左拉一票人出来单干是他们的企业文化。 所以现在市面上主流的流程引擎就一共有三个: Activiti Flowable Camunda 这三个各有特点: Activiti 目前是侧重云,他目前的设计会向 Spring Cloud、Docker 这些去靠拢。 Flowable 核心思想还是在做一个功能丰富的流程引擎工具,除了最最基础的工作流,他还提供了很多其他的扩展点,我们可以基于 Flowable 实现出许多我们想要的功能(当然这也是小伙伴们觉得 Flowable 使用复杂的原因之一)。 Camunda 相对于前两个而言比较轻量级,Camunda 有一个比较有特色的功能就是他提供了一个小巧的编辑器,基于 bpmn.io 来实现的(松哥之前已经发文讲过了)。如果你的项目需求是做一个轻巧的、灵活的、定制性强的编辑器,工作流是嵌入式的,那么可以选择 Camunda。 如果仔细比较起这三个的差异,能列一个长长的表格,这个网上也有不少人都总结过了,松哥这里也就不啰嗦了。 3. 流程图 既然有三个不同的工作流,那么三个不同的工作流画出来的流程图是否都各不相同呢? 不是的。 工作流程图这块其实有一个统一的标准,那就是 BPMN。BPMN 全称是 Business Process Model and Notation,中文译作业务流程模型和标记法,这个中文太绕口了,还是简称 BPMN 吧。 这是一套图形化表示法,用图形来表示业务流程模型。BPMN 最初由业务流程管理倡议组织(BPMI, Business Process Management Initiative)开发,BPMI 于 2005 年与对象管理组织(OMG, Object Management Group)合并,并于 2011 年 1 月 OMG 发布 2.0 版本,同时改为现在的名称。 一句话,就是流程图这块有一个特别古老的规范,那就是 BPMN,而我们前面所说的无论是 Activiti、Flowable 还是 Camunda,都是支持这个规范的,所以呢,无论你使用哪一个流程引擎,都可以使用同一套流程图。 那么这个规范究竟都说了些什么事情呢? 我们以上面生产笔记本的流程图为例,来和小伙伴们做一个简单介绍: 从上图中可以看到,一个流程图中主要包含四方面的内容: 事件 连线 任务 网关 我们一个一个来说。 事件 首先在一个流程图中应该有开始事件和结束事件,也就是上图大家看到的两个圆圈。另外还有一些中间事件、边界事件等。举个中间定时事件的例子,比如用户下单之后,可以有一个中间定时事件,延迟 5 分钟发货。 连线 连线就是将事件、任务、网关等连在一起的线条,一般情况下就是普通连线,有的时候连线会有一些条件,例如松哥之前文章和大家分享的请假,如果经理同意请假申请,就走哪一个线条,如果经理不同意请假申请,就走哪一个线条。对应上图的笔记本生产,如果经理审批通过,就载入图纸准备生产,如果经理审批不通过,就重新设计。 任务 任务这块其实有很多分类。 如果细分大致上可以分为如下几种: 接收任务 在上面的流程图中,等待准备工作完成这一项就是一个接收任务。这个任务里并不需要额外做什么事情,流程到这一步就自动停下来了,需要人工去点一下,推动流程继续向下执行。 发送任务 这个一般用来把消息发送给外部参与者。 服务任务 这个一般由系统自动完成,其实说白了就是我们的一个自定义类,可以在一个自定义类里边完成想要做的事情。 脚本任务 一个自动化活动。当流程执行到脚本任务时,自动执行相应的脚本。 业务规则任务 BPMN2.0 新引入用来对接业务规则引擎,业务规则任务用于同步执行一个或多个规则。 用户任务 用于为那些需要由人工参与者完成的工作建模。 虽然细分类别很多,但是仔细看,其实这几种又可以归为两大类: 用户任务:表示人工要介入做的事情。比如同意与否,或者输入一些参数,要让人工完成任务,就需要一个表单系统,让人工输入数据,或者显示数据给人看,这也是为什么用户任务和表单系统结合在一起的原因,用户任务需要用户向引擎提交一个完成任务的动作,否则流程会暂停在这里等待。 服务任务:表示机器自动做的事情。调用服务的任务,这个服务可以是一个 Spring JavaBean,也可以是一个远程 REST 服务,流程会自动执行服务任务。 活动 活动可以算是一种特殊的任务。活动可以调用另外一个流程使之作为当前流程的子流程去运行。活动也可以分为用户活动、脚本活动等等。从显示上来说,活动比任务边框深一些。仅此而已。 网关 网关要是细分起来,也有很多不同类型的网关。 互斥网关 这种网关也叫排他性网关,我们之前请假流程中的那个网关,就是互斥网关。这种网关有且仅有一个有效出口。 相容网关 这种网关会有多个出口,只要条件满足,都会执行。 事件网关 事件网关是通过中间事件驱动,它在等待的事件发生后才会触发决策。基于事件的网关允许基于事件作出决策。 并行网关 并行网关一般是成对出现的,上面生产笔记本的那个流程中,生产屏幕、键盘等并行操作,就是通过并行网关来实现的。 好啦,这就是关于流程引擎的一些基本概念,捋顺了这些基本概念,在回过头看我们前面几篇关于流程引擎的文章,应该会有一些不一样的理解: Spring Boot 整合流程引擎 Flowable,so easy! SpringBoot+Vue+Flowable,模拟一个请假审批流程! 49张图带领小伙伴们体验一把 Flowable-UI Spring Security + Vue + Flowable 怎么玩?

优秀的个人博客,低调大师

Tigon MyBatis v0.0.8 发布,极简 MyBatis Mapper 增强

Tigon MyBatis v0.0.8 已经发布,为 MyBatis Mapper 提供增强,设计精巧,代码量很少,代码洁癖工程师的朋友 此版本更新内容包括: 优化插入生成Key逻辑,之前通过拦截器方式实现,在高并发环境下存在Bug 删除了100多行代码,今天又变强了 详情查看:https://gitee.com/chyxion/tigon-mybatis/releases/v0.0.8 Tigon MyBatis 简介 Tigon MyBatis为Spring工程中MyBatis的Mapper提供增强,主要有以下特点 代码又少又壮,绝不做多余的事情 仅需Mapper继承接口,实现增删改查,无额外配置,爽到没女朋友 用完即走,毫不留恋 开始使用 引入Maven依赖 <dependency> <groupId>me.chyxion.tigon</groupId> <artifactId>tigon-mybatis</artifactId> <version>0.0.8</version> </dependency> 使用示例 定义Entity package me.chyxion.tigon.mybatis.entity; import lombok.Getter; import lombok.Setter; import java.util.Date; import lombok.ToString; import java.io.Serializable; import me.chyxion.tigon.mybatis.Table; import me.chyxion.tigon.mybatis.NotUpdate; import me.chyxion.tigon.mybatis.NotUpdateWhenNull; @Getter @Setter @ToString @Table("tb_user") public class User implements Serializable { private static final long serialVersionUID = 1L; private Integer id; // 标记账户不被更新 @NotUpdate private String account; // 当手机号为null不被更新 @NotUpdateWhenNull private String mobile; private String name; private Gender gender; private String password; private Date birthDate; private String city; private String avatar; private Boolean active; private String remark; private String createdBy; private Date createdAt; private String updatedBy; private Date updatedAt; public enum Gender { MALE, FEMALE } } 定义Mapper package me.chyxion.tigon.mybatis.mapper; import java.util.List; import me.chyxion.tigon.mybatis.BaseMapper; import org.apache.ibatis.annotations.Mapper; import me.chyxion.tigon.mybatis.entity.User; @Mapper public interface UserMapper extends BaseMapper<Integer, User> { } 注入Mapper对象 @Autowired private UserMapper mapper; I. 插入 val user = new User(); user.setName("Donghuang"); user.setAccount("donghuang"); user.setMobile("137647788xx"); user.setPassword(RandomStringUtils.randomAlphanumeric(16)); user.setGender(User.Gender.MALE); user.setBirthDate(DateUtils.parseDate("1994-04-04")); user.setCity("Shanghai"); user.setActive(true); user.setRemark("Uncle Donghuang"); user.setCreatedBy("donghuang"); user.setCreatedAt(new Date()); // 插入单条记录 mapper.insert(user); val user1 = new User(); user1.setName("Gemily"); user1.setAccount("gemily"); user1.setMobile("15770780xxx"); user1.setPassword(RandomStringUtils.randomAlphanumeric(16)); user1.setGender(User.Gender.FEMALE); user1.setBirthDate(DateUtils.parseDate("1990-06-06")); user1.setCity("Hangzhou"); user1.setActive(true); user1.setCreatedBy("donghuang"); user1.setCreatedAt(new Date()); val user2 = new User(); user2.setName("Luffy"); user2.setAccount("luffy"); user2.setMobile("137647799xx"); user2.setPassword(RandomStringUtils.randomAlphanumeric(16)); user2.setGender(User.Gender.MALE); user2.setBirthDate(DateUtils.parseDate("1997-07-07")); user2.setCity("East sea"); user2.setActive(true); user2.setRemark("Luffy"); user2.setCreatedBy("donghuang"); user2.setCreatedAt(new Date()); // 批量插入记录 mapper.insert(Arrays.asList(user1, user2)); II. 查询 根据ID查询单个对象 val id = 1154; // 根据主键查询单条记录 val user = mapper.find(id); 根据属性查询单个对象 // 根据属性account, mobile查询单个对象 val user = mapper.find( new Search("account", "donghuang") .eq("mobile", "137647788xx")); 根据属性查询列表 // 根据属性birthDate, gender查询数据列表 // 查询结果根据属性birthDate升序排序 // 返回数据限制42条 val users = mapper.list(new Search() .between("birthDate", DateUtils.parseDate("1982-04-04"), DateUtils.parseDate("1994-04-04") ) .eq("gender", User.Gender.MALE) .asc("birthDate") .limit(42)); Search对象支持的API ascOrder ASC 列升序排序 descOrder DSC 列降序排序 orderByOrder by 列属性排序 betweenBetween two values 属性列属于2个值之间 buildBuild query criterion 自定义构建一个属性列查询条件 startsWithValue starts with string 属性列以字符串开头,等同于col like 'val%' endsWithValue ends with string 属性列以字符串结尾,等同于col like '%val' containsValue contains string 属性列包含字符串,等同于col like '%val%' likeValue like 属性列与字符串相似 eqEquals 属性列等于 neNot equals 属性列小于或等于 gtGreater than 属性列大于 gteEquals or greater than 属性列大于或等于 ltLess than 属性列小于 lteEquals or less than 属性列小于 inIn values 属性列属于集合 notInNot in values 属性列不属于集合 isNullValue is null 属性列为null notNullValue is not null 属性列不为null isTrueValue is true 属性列为true isFalseValue is false 属性列为false limitReturn rows limit 查询/更新结果行数限制 offsetReturn rows offset 查询结果偏移行数 andAnd anotherSearch且另外一个Search对象 orOr anotherSearch或另外一个Search对象 III. 更新 通过Entity根据ID更新 // 根据主键查询记录 val user = mapper.find(1); user.setName("东皇大叔"); user.setUpdatedBy("SYS"); user.setUpdatedAt(new Date()); // 更新单个实体对象 mapper.update(user); 通过Map<String, Object>更新 val update = new HashMap<String, Object>(6); update.put("name", "东皇大叔"); update.put("updatedBy", "SYS"); update.put("updatedAt", new Date()); // 通过Map更新ID为1的记录 mapper.update(update, 1); // 效果同上 // mapper.update(update, new Search("id", 1)); // mapper.update(update, new Search(1)); 更新列为NULL // 更新id为274229记录的属性列remark为null mapper.setNull("remark", 274229); // 更新id为1154记录的属性列remark为null mapper.setNull("remark", new Search("id", 1154)); // 更新全表的属性列remark为null,小心操作!!! mapper.setNull("remark", new Search()); IV. 删除 通过ID删除数据 // 根据主键删除记录 mapper.delete(1); 通过Search对象删除数据 // 根据属性ID删除记录 mapper.delete(new Search("id", 1)); // 等同于 mapper.delete(1); V. 杂项 除了上面说到的一些基础增删改查操作,还有一些实用功能,如@Transient@UseGeneratedKeys@NoPrimaryKey@NotUpdateWhenNull@RawValue等注解,插入、更新前回调,以及支持扩展自定义的方法等。 配置说明 SpringBoot项目,无需其他操作,引入依赖即可 Spring项目,注册Beanme.chyxion.tigon.mybatis.TigonMyBatisConfiguration 业务Mapper继承me.chyxion.tigon.mybatis.BaseMapper或相关衍生Mapper,Base(Query, Insert, Update, Delete)Mapper

优秀的个人博客,低调大师

大数据,Hadoop,存储应用的第三极

数字化转型是当今IT应用的标杆和旗帜,也是讨论最热门的话题。在我看来,数字化转型有两个方面的含义:一是与生产、业务相关的过程尽可能实现数字化,能保留数据全部进行保留;二是基于数据展开分析,动用大数据、人工智能等技术手段,透视数据背后的秘密,产生价值,知道企业生产和业务决策。 对于数字化转型的第一阶段,绝对是一个“烧钱”的阶段,但对于企业来说,这是一个必要条件,具备了数字化的能力不一定确保企业成功,但没有第一阶段数字化、数据积累,企业在未来的竞争中,一定打不过哪些数字化成功转型的企业。与第一阶段的“烧钱”相比,第二个阶段对数据进行洞察,将更加重要,也更为关键,这就离不来大数据技术。 经过多年的信息化应用,企业积累了大量的数据,但以往这些数据无法有效关联在一起,Hadoop分布式系统基础架构的出现,为大数据技术应用奠定基础,创造了条件。不同于传统磁盘阵列,也不同于ServerSAN或者超融合的数据存储和组织方式,Hadoop会成存储市场上的第3类存储吗? Hadoop会成存储第3级吗? Hadoop,数据存储和导入 无论是单独构建集群系统,规模视情况而定?还是选用市场现有的大数据一体机,用户都需要一个单独平台进行大数据分析处理,系统构建完成之后,首先要把数据导入。 企业数据如何导入Hadoop系统?系统又如何组织数据的呢?为此,我请教百分点大数据的专家获知,可以借助不同的工具,对于数据进行导入。 不同数据类型,需要采用的不用工具。以数据库数据为例,要采用的工具是Sqoop,可以将一个关系型数据库(例如 : MySQL、Oracle、PostgreSQL等)中的数据导进到Hadoop(Hive)的HDFS中,也可以反过来将HDFS数据导进到关系型数据库中。针对非结构化数据,例如文本数据、IoT(物联网)机器数据等,需要使用Flume,它是Cloudera提供的一个海量日志采集、聚合和传输的系统,同时Flume也提供对数据进行简单处理,并写到各种数据接受方(可定制)。需要稍加说明的是,图片大小不同,接入介质(这里指MongoDB、Hbase或HDFS)不同,其中,有些介质适合小文件数据处理,有些适合处理大文件,因此,要根据非结构化数据的特点,分别加以存储。 “标签”体系是基础 当数据就绪之后,接下来就要由具有行业经验、业务经验的专家,结合业务系统和业务形态构建数据的标签体系。根据介绍,系统为一个用户打的各种标签高达近万种,其颗粒度之细致超乎想象。可以毫不夸张的说,机器甚至比你更加了解你自己。对于人来说,做过事情经过一段时间会被遗忘,但机器不会,主要数据不删除,机器永远不会忘记。 标签体系是用户业务画像的基础,通过各种灵活业务查询,就可以演变出千变万化的业务创新应用,可以是解决现有业务系统的问题,如性能问题、系统预警问题;也可以针对业务提供创新的业务服务,例如零售行业的个性化推荐、金融防欺诈和反洗钱等,这些业务应用有些属于离线业务分析,有些则涉及在线的数据处理能力。不同系统,需要采用不同的技术手段,可以列式数据库,也可以是Spark等。 以某省交管部门为例,随着数据量的不断增加,他们所采用的关系数据库就出现了性能不足的问题。对此,他们引入了大数据的技术,通过分布式数据处理,成功解决系统存在的问题。 从本质上说,大数据技术和关系型数据库所提供服务,从方向上是一致的。关系型数据库也提供了数据存储、数据查询,数据仓库ETL等一系列技术,提供在线数据分析等服务。与之相比,大数据应用所提供数据颗粒度更细,分布式系统能够处理的数据量更大,数据分析技术和手段更加多样性。 如今,随着人工智能,机器学习等技术的成熟,经过大量数据的训练和矫正,数据建模分析的效果愈发显现了出来。以零售行业个性化推荐应用为例,已经成为了行业应用的标配,效果显著。 小结 大数据应用为人类工作生活展示了美丽画卷,所谓理想丰满,现实骨干,如今大数据应用现状并不令人满意,问题并不在Hadoop等技术方向上,方向没有错,但与此同时,Hadoop技术复杂性成为了应用的限制门槛。 必须简化技术的复杂度,为此百分点等厂商推出了像BD-OS这样的大数据平台,帮助用户简化和使用各种分析手段和工具。目前,行业的龙头企业正在积极引入这些技术,因此,大数据技术和行业应用还在结合之中,行业应用的爆发还需要一段时间的积累,所谓不鸣则已,一鸣惊人! 大数据普遍爆发也许真的用不了太长的时间! 本文转自d1net(转载)

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册