hosts

github # GitHub Start 192.30.253.112 Build software better, together 192.30.253.119 gist.github.com 151.101.184.133 assets-cdn.github.com 151.101.184.133 raw.githubusercontent.com 151.101.184.133 gist.githubusercontent.com 151.101.184.133 cloud.githubusercontent.com 151.101.184.133 camo.githubusercontent.com 151.101.184.133 avatars0.githubusercontent.com 151.101.184.133 avatars1.githubusercontent.com 151.101.184.133 avatars2.githubusercontent.com 151.101.184.133 avatars3.githubusercontent.com 151.101.184.133 avatars4.githubusercontent.com 151.101.184.133 avatars5.githubusercontent.com 151.101.184.133 avatars6.githubusercontent.com 151.101.184.133 avatars7.githubusercontent.com 151.101.184.133 avatars8.githubusercontent.com # GitHub End

2020-09-07

基于electron、vue和antd开发一个桌面应用

其实electron+vue开发桌面应用早有先例electron-vue项目,但是这个项目已经好久没有维护,于是乎想自己集成一下,纯为练手,本文主要记录下了electron集成vue和antd的过程。 一、开发环境 Node版本:node(v10.16.0) + npm(6.13.0) + vue-cli(@vue/cli 4.5.4) 编辑器:VSCode 操作系统:macos(10.14.6) 二、初始化一个vue项目 打开命令行,执行以下代码,创建一个项目文件夹,然后在这个文件夹里初始化一个vue项目 cd desktop mkdir electron-demo && cd electron-demo vue create ftms-app 执行vue create时,vue-cli会通过交互文本的形式引导我们自定义vue项目的初始配置 第一步 选择预设配置或者手动配置,这里我们选择Manually select features,接着会手动选择项目特性 第二步 选择项目特性,这里选择Babel Router Vuex 第三步 选择vue版本,这里选择2.x,3.x为预览版 第四步 是否启用history mode,这里选择启用 第五步 选择Babel ESlint等插件的配置文件位置,这里选择package.json 第六步 是否将这些配置设置为预设,这里选择否 等初始化完成后执行以下代码进入项目根目录,启动vue项目 cd ftms-app npm run serve 至此,一个基本的vue项目初始化完毕,访问链接http://localhost:8080可看到如下页面 三、添加electron支持 命令行执行以下命令添加electron-builder插件 vue add electron-builder 会提示选择electron版本,这里选择最新版^9.0.0 安装成功后项目根目录会自动生成一个background.js文件,并且在package.json文件会添加以下代码 现在执行如下命令可以启动electron了 npm run electron:serve 启动的过程会相对漫长(这个界面要Fuck GFW5次,曾让我一度怀疑我的配置有问题) 看到这个页面就证明vue和electron集成成功了 四、添加antd支持 执行如下命令添加antd npm i --save ant-design-vue 修改项目中main.js,添加antd插件,修改后main.js如下 ...

2020-08-27

emacs figlet

2020-08-20

抛弃 Postman 投入 IDEA New Http Client 怀抱

都2020年了,idea也用了大概两三年了,开发工具基本都换成了jetbrain全家桶,pycharm、webstorm、phpstorm、goland、datagrip,竟然今天才发现idea自带的Http Client😂。找了几个刚开发的api接口试用了一番,突然就感觉Postman不够香了! 开始 idea新版的httpclient是直接嵌入到编辑区的,新建一个后缀为http的文件,双击打开后按一定格式编写代码后,即可开始测试api接口 鼠标移动到文件编辑区的右上方有个悬浮按钮,分别为查看历史和示例按钮 点击示例按钮可以看到官方给的常用的http请求示例 按照示例文件编写好代码后,点击左侧的运行按钮即可发送请求 点击查看历史按钮可以看到发送请求的历史记录 环境变量 把httpclient直接嵌入编辑器,够简单够纯粹,已经让我爱不释手了,没想到还有意外惊喜 - 支持定义环境变量。 在项目根目录下新建一个名为http-client.env.json的配置文件,或者如果环境变量里包含敏感信息新建名为http-client.private.env.json的配置文件(idea已经帮我们把这个文件加入git的ignore列表),定义环境变量格式如下: { "local": { "host": "localhost:8081" }, "prod": { "host": "bovod.org" } } 这样就可以在代码中通过{{变量名}}的方式使用环境变量 其他功能 通过简单的回调函数测试响应结果(暂时没用到,可在官方示例里看到) 总结 比Postman更轻量,相比图形界面更简洁,更纯粹!

2020-07-22

用syncthing做一个同步盘

背景 公司一台电脑,家里一台电脑,经常同步文件,正在使用的是onedrive,由于网络环境原因,经常被墙😒。之前尝试过自己搭建私有云盘(用的是OwnCloud),不够轻量,安装略麻烦,尝试过Resilio Sync,总体好用,但是收费的,也装过syncthing(不知道为啥没接着用),现在重新把syncthing用起来,看香不香! 计划同步的电脑: 电脑0🖥,阿里云vps,linux系统(作为同步中介) 电脑1💻,公司笔记本,macos系统 电脑2🖥,家里台式机,win10系统 下载 下载地址https://syncthing.net/downloads/(由于网络环境原因,非常非常非常慢,文末我会给个分享链接👇) 电脑0🖥作为中介只下载syncthing基本包即可 电脑1💻和电脑2🖥为了方便操作,根据操作系统分别下载syncthing-macos和SyncTrayzor图形客户端 启动 电脑0🖥解压下载好的syncthing-linux-amd64-v1.7.0.tar.gz直接运行文件夹内syncthing文件 第一次启动syncthing会在用户目录自动生成syncthing的配置文件。电脑0🖥因为需要外网访问,需要修改下配置文件~/.config/syncthing/config.xml将<address>127.0.0.1:8384</address>改成<address>0.0.0.0:8384</address>。修改完成后重启syncthing。 电脑1💻上访问<电脑0🖥的ip>:8384后即可看电脑0🖥的syncthing管理控制台,刚打开会提示设置密码 点击右上角操作→显示ID可以看到电脑0🖥的机器id 电脑1💻启动syncthing-macos(syncthing-macos会自动帮你启动syncthing服务)可看到电脑1💻的syncthing管理控制台 电脑1💻的syncthing管理控制台右下角点击添加远程设备,输入电脑0🖥的机器id,选择共享的文件夹进行共享,这时候电脑0🖥会收到添加请求,点击确定即可完成共享(当然,反过来电脑0🖥添加电脑1💻也是同理) 比较实用的功能 可以配置忽略列表(支持通配符) 可以设置共享文件夹类型:接受发送(默认)、仅接收、仅发送 同步文件时可能报错 Error on folder “Sync” (hmqcv-br6sh): folder marker missing 在同步文件夹内新建.stfolder文件夹(windows需要在cmd里新建)

2020-07-09

微信网页禁用字体大小设置

(function() { if (typeof WeixinJSBridge == "object" && typeof WeixinJSBridge.invoke == "function") { handleFontSize(); } else { if (document.addEventListener) { document.addEventListener("WeixinJSBridgeReady", handleFontSize, false); } else if (document.attachEvent) { document.attachEvent("WeixinJSBridgeReady", handleFontSize); document.attachEvent("onWeixinJSBridgeReady", handleFontSize); } } function handleFontSize() { // 设置网页字体为默认大小 WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize': 0 }); // 重写设置网页字体大小的事件 WeixinJSBridge.on('menu:setfont', function () { WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize': 0 }); }); } }) ();

2020-06-30

windows 命令

显示文件短名称(非8dot3文件会生成短名称) dir /x

2020-06-24

springboot 切面开发

pom.xml 添加 AOP 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 入口类添加@EnableAspectJAutoProxy注解开启AOP 编写切面类 @Aspect @Component public class AuthAspect { @Autowired HttpServletRequest request; @Autowired protected WaterStationService waterStationService; @Before("execution(* cn.agoodwater.admin.controller.*.*(..))") public void proceed(JoinPoint joinPoint) throws Throwable { System.out.println("进入切点"); String remoteUser = request.getRemoteUser(); if(StringUtils.isNotBlank(remoteUser) && !"admin".equalsIgnoreCase(remoteUser)){ WaterStationBO ws = waterStationService.queryByManager(remoteUser); Object[] obj = joinPoint.getArgs(); for (Object obj1 : obj) { if(!(obj1 instanceof HttpServletResponse)){ Method setWsIdMethod = null; Class<?> aClass = obj1.getClass(); try { setWsIdMethod = aClass.getDeclaredMethod("setWsId",Integer.class); } catch (Exception e) { // } if(setWsIdMethod!=null){ setWsIdMethod.invoke(obj1,ws.getId()); } } } } } }

2020-06-23

今天父亲节

今天儿子还祝我父亲节快乐,估计他都不知道什么是父亲节,我知道,却再也说不出父亲节快乐! 下午去新华区转了转,买了辆三轮,带着他娘儿俩沿解放路一路开回家,微风习习,算是提前感受了退休后的生活!日子慢下来过,仿佛真的就变长了,也更有滋味了! 昨天本来是回老家验车的,起晚了,也就取消了,微信群里,小姑发来爷爷的视频,90多岁了,身体硬朗,没回家,看一看视频心里也开心得不得了!隔着屏幕我替我父亲向我父亲的父亲问了声父亲节快乐! !!! !!!

2020-06-21

springboot 集成 websocket

添加 websocket 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> 添加配置WebSocketConfig import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } } 编写一个WebSocketServer用来收发消息 import cn.agoodwater.admin.ws.vo.WsMsg; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; @Slf4j @ServerEndpoint("/ws/{sid}") @Component public class WebSocketServer { //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 private static int onlineCount = 0; //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>(); //与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; //接收sid private String sid=""; /** * 连接建立成功调用的方法*/ @OnOpen public void onOpen(Session session,@PathParam("sid") String sid) { this.session = session; webSocketSet.add(this); //加入set中 addOnlineCount(); //在线数加1 log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount()); this.sid=sid; try { sendMessage(0,"连接成功"); } catch (IOException e) { log.error("websocket IO异常"); } } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { webSocketSet.remove(this); //从set中删除 subOnlineCount(); //在线数减1 log.info("有一连接关闭!当前在线人数为" + getOnlineCount()); } /** * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息*/ @OnMessage public void onMessage(String message, Session session) { log.info("收到来自窗口"+sid+"的信息:"+message); //群发消息 for (WebSocketServer item : webSocketSet) { try { item.sendMessage(message);// 初始化信息 } catch (IOException e) { e.printStackTrace(); } } } /** * * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { log.error("发生错误"); error.printStackTrace(); } public void sendMessage(Integer type,String message) throws IOException { message = new WsMsg<>(type,message).toString(); this.session.getBasicRemote().sendText(message); } /** * 实现服务器主动推送 */ public void sendMessage(String message) throws IOException { message = new WsMsg<>(message).toString(); this.session.getBasicRemote().sendText(message); } /** * 群发自定义消息 * */ public static void sendInfo(String message,@PathParam("sid") String sid) throws IOException { log.info("推送消息到窗口"+sid+",推送内容:"+message); for (WebSocketServer item : webSocketSet) { try { //这里可以设定只推送给这个sid的,为null则全部推送 if(sid==null) { item.sendMessage(message); }else if(item.sid.equals(sid)){ item.sendMessage(message); } } catch (IOException e) { continue; } } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSocketServer.onlineCount++; } public static synchronized void subOnlineCount() { WebSocketServer.onlineCount--; } } 如果使用了 spring security 需要给 ws 地址放行 .antMatchers("/ws/**").permitAll() 如果使用了 nginx 作反向代理,需要添加如下配置 proxy_read_timeout 3600s; ## 设置超时时间 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";

2020-06-18