├── .gitignore ├── .vscode └── settings.json ├── Color ├── README.md └── color.js ├── DemoQuartz ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── Configuration.xml ├── README.md ├── demoquart.md ├── generatorConfig.xml ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DemoApplication.java │ │ │ ├── MyConfiguration.java │ │ │ ├── contronller │ │ │ └── QuartContronller.java │ │ │ ├── jobs │ │ │ ├── QuartzJob.java │ │ │ └── QuartzJobTwo.java │ │ │ ├── requestparam │ │ │ └── QuartzRequest.java │ │ │ └── uitl │ │ │ ├── BaseControuller.java │ │ │ ├── BaseResponse.java │ │ │ └── QuartzTool.java │ └── resources │ │ ├── application.properties │ │ ├── application.yml │ │ ├── mybatis-config.xml │ │ └── spring-mybatis.xml │ └── test │ └── java │ └── com │ └── example │ └── demo │ └── DemoApplicationTests.java ├── FuncJsRay ├── Rx.js ├── WebWork.js ├── index.html ├── index.js └── web_work.js ├── HT FOR WEB 自定义菜单 ├── config-diycomponent.js ├── config-diydisplay.js ├── config-diymenu.js └── config-handleEvent.js ├── JavaHttpTool ├── HttpUtil.java └── README.md ├── Js-Fuck-Demo ├── index.html └── index.js ├── LICENSE ├── NodeDuanDian ├── index.html ├── index.js ├── package-lock.json └── package.json ├── README.md ├── SherpaOnnx └── SherpaOnnx.swift ├── SparkleUpdate ├── CustomUpdateController.swift └── UpdateNotificationWindow.swift ├── WebPageNotes ├── chromePlug │ ├── .vscode │ │ └── settings.json │ ├── background.html │ ├── background.js │ ├── chromePlug.zip │ ├── css │ │ └── hz-content.css │ ├── img │ │ ├── icon │ │ │ └── icon.png │ │ └── popup │ │ │ ├── arrow.png │ │ │ ├── del.png │ │ │ ├── pen.png │ │ │ ├── remove.png │ │ │ ├── select.png │ │ │ ├── serial.png │ │ │ ├── sure.png │ │ │ └── text.png │ ├── js │ │ ├── libs │ │ │ ├── axio.js │ │ │ ├── fabric.min.js │ │ │ ├── html2canvas.js │ │ │ └── jquery.min.js │ │ └── src │ │ │ ├── content-msg.js │ │ │ ├── data.js │ │ │ ├── fabrictool │ │ │ ├── config-data.js │ │ │ ├── draws │ │ │ │ ├── arrow.js │ │ │ │ ├── index.js │ │ │ │ └── serial.js │ │ │ ├── event.js │ │ │ ├── index.js │ │ │ └── setting.js │ │ │ ├── global-data.js │ │ │ ├── main.js │ │ │ ├── popup.js │ │ │ ├── tool │ │ │ ├── element.js │ │ │ ├── event.js │ │ │ └── index.js │ │ │ └── tools.js │ ├── manifest.json │ ├── note_canvas.zip │ └── popup.html ├── codeSign.zip └── codeSign │ ├── .vscode │ └── settings.json │ ├── background.html │ ├── background.js │ ├── css │ ├── atom-one-dark.min.css │ ├── wtechtec-form.css │ ├── wtechtec-loading.css │ └── wtechtec.css │ ├── img │ └── icon │ │ └── icon.png │ ├── js │ ├── libs │ │ ├── axio.js │ │ ├── beautify-css.min.js │ │ ├── beautify-html.min.js │ │ ├── codemirror │ │ │ ├── addon │ │ │ │ ├── css-hint.js │ │ │ │ ├── show-hint.css │ │ │ │ └── show-hint.js │ │ │ ├── lib │ │ │ │ ├── codemirror.css │ │ │ │ └── codemirror.js │ │ │ └── mode │ │ │ │ └── css.js │ │ ├── fabric.min.js │ │ ├── highlight.min.js │ │ ├── html2canvas.js │ │ └── jquery.min.js │ └── src │ │ ├── atom │ │ ├── atom.js │ │ ├── base.js │ │ ├── format.js │ │ ├── gather.js │ │ └── style-mixin.js │ │ ├── fabrictool │ │ ├── config-data.js │ │ ├── draws │ │ │ ├── arrow.js │ │ │ ├── index.js │ │ │ └── rect.js │ │ ├── event.js │ │ └── fabric-dom.js │ │ ├── form-view │ │ ├── dom.js │ │ ├── event.js │ │ ├── index.js │ │ ├── temp │ │ └── temp.js │ │ ├── global.js │ │ ├── main.js │ │ ├── top-opt │ │ ├── config.js │ │ ├── dom.js │ │ ├── event.js │ │ ├── index.js │ │ └── view.js │ │ └── units │ │ ├── color.js │ │ ├── dom-ui.js │ │ └── tools.js │ ├── manifest.json │ └── popup.html ├── Web_UI └── mobile_table │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ └── tsconfig.json ├── Wx-Canvas-Dynamic ├── ThumbsUpAni.js └── index │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss ├── Wx-QianMing ├── draw.js ├── index.js ├── index.json ├── index.wxml ├── index.wxss └── wordUtils.js ├── Wx-美团日期 ├── conmon.js ├── index.js ├── index.json ├── index.wxml └── index.wxss ├── bmgame ├── demo1 │ ├── .vscode │ │ └── settings.json │ ├── img │ │ └── firetorch_1.jpg │ ├── index.html │ ├── js │ │ └── index.js │ └── libs │ │ ├── OrbitControls.js │ │ └── three.js ├── server.tar └── server │ ├── game │ └── index.html │ ├── game3D │ ├── backgammon.html │ ├── js │ │ ├── backgammon │ │ │ ├── game.js │ │ │ ├── index.js │ │ │ ├── piece.js │ │ │ └── player.js │ │ ├── index.js │ │ └── rubiks │ │ │ ├── components │ │ │ ├── camera.js │ │ │ ├── renderer.js │ │ │ └── scene.js │ │ │ ├── core │ │ │ ├── MouseControl.js │ │ │ ├── control.js │ │ │ ├── cube.js │ │ │ ├── cubeData.js │ │ │ ├── cubeState.js │ │ │ └── square.js │ │ │ ├── index.js │ │ │ └── util │ │ │ ├── math.js │ │ │ └── transform.js │ ├── libs │ │ ├── OrbitControls.js │ │ ├── jquery.js │ │ ├── socket.io.min.js │ │ └── three.js │ ├── readme.md │ ├── rubiks.html │ └── textures │ │ ├── square-outline-textured.png │ │ └── square-outline.png │ ├── index.js │ ├── package.json │ └── piece.js ├── canvan-chart ├── index.html └── js │ ├── d3.min.js │ ├── drawutil.js │ ├── scalelinear.js │ ├── scaleordinal.js │ ├── scalepie.js │ ├── wxcharts-min.js │ └── wxcharts.js ├── data-proxy └── proxy.js ├── echartBmap ├── .vscode │ └── settings.json ├── README.md ├── dist │ ├── echarts.min.js │ └── extension │ │ └── bmap.min.js └── index.html ├── emojimixer ├── emojconfig.js └── index.html ├── exportExecl ├── Blob.js ├── Export2Excel.js ├── Export2Zip.js └── README.md ├── go_makemask ├── font.ttf ├── go.mod ├── go.sum ├── main.go ├── test-water.jpg ├── test.jpg └── watermarker │ └── water_marker.go ├── golang ├── imooc-maze │ ├── maze.go │ └── maze.in └── share_car │ ├── .eslintrc.js │ ├── app.js │ ├── app.json │ ├── app.wxss │ ├── assets │ └── images │ │ ├── car.png │ │ ├── maker-car.png │ │ ├── person.png │ │ └── postion.png │ ├── components │ └── word-cloud │ │ ├── README.md │ │ ├── index.js │ │ ├── index.json │ │ ├── index.wxml │ │ ├── index.wxss │ │ ├── wordcloud.js │ │ └── wrod-cloud.js │ ├── mock │ └── divre_data.js │ ├── pages │ ├── driving │ │ ├── index.js │ │ ├── index.json │ │ ├── index.wxml │ │ └── index.wxss │ ├── index │ │ ├── index.js │ │ ├── index.json │ │ ├── index.wxml │ │ └── index.wxss │ ├── register │ │ ├── index.js │ │ ├── index.json │ │ ├── index.wxml │ │ └── index.wxss │ ├── test │ │ ├── index.js │ │ ├── index.json │ │ ├── index.wxml │ │ └── index.wxss │ └── unlock │ │ ├── index.js │ │ ├── index.json │ │ ├── index.wxml │ │ └── index.wxss │ ├── project.config.json │ ├── project.private.config.json │ └── sitemap.json ├── html5-Qrcode ├── README.md ├── index.html └── lib │ ├── jquery-1.8.0.js │ ├── my.css │ ├── qrcode.js │ ├── qrcode.lib.min.js │ ├── quagga.min.js │ └── zepto.js ├── htmlExportPDF ├── html2canvas.min.js └── jspdf.js ├── i18n-processor ├── README.md ├── bin │ └── i18n-processor.js ├── package.json ├── src │ ├── cli.ts │ ├── core │ │ ├── ast.ts │ │ ├── processor.ts │ │ └── types.ts │ └── utils │ │ ├── common.ts │ │ └── file.ts ├── tests │ └── TestComponent.tsx └── tsconfig.json ├── mcp-servers ├── gemini.js ├── mcp-tools.js ├── package.json ├── prompts │ └── gemini.js └── utils.js ├── mcp-weather-server ├── .gitignore ├── README.md ├── package.json ├── src │ ├── WeatherServer │ │ ├── index.ts │ │ ├── mock.ts │ │ └── type.ts │ ├── demo.ts │ └── index.ts └── tsconfig.json ├── mobileEvent ├── EventUtilSlider.js └── README.md ├── node-websocket ├── index.html ├── package.json ├── server.js └── ws.js ├── online_code ├── online_run.html ├── proxy_iframe.html └── stringify.js ├── protobf-demo ├── package.json ├── proto │ ├── proto.js │ └── user.proto └── server.js ├── proxy-web ├── app.js └── package.json ├── pyRAG ├── .env ├── Embeddings.py ├── MyVectorDBConnector.py ├── PDFFileLoader.py ├── a-practical-guide-to-building-agents.pdf ├── index.py └── 如何让 LLM 应用性能登峰造极.pdf ├── pyRTC ├── .env.exp ├── app.py ├── models │ └── README.md ├── requirements.txt └── static │ └── index.html ├── react-web-pro-master.zip ├── rrweb-demo ├── README.md ├── demo │ ├── data.js │ ├── index.html │ ├── player.html │ └── type.js └── rrWeb-demo │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── index.html │ ├── package.json │ ├── public │ └── vite.svg │ ├── src │ ├── App.css │ ├── App.jsx │ ├── assets │ │ └── react.svg │ ├── data.js │ ├── index.css │ └── main.jsx │ └── vite.config.js ├── socketIoDemo ├── README.md ├── client │ └── dist │ │ ├── anime.es.js │ │ ├── anime.js │ │ ├── anime.min.js │ │ ├── chart.css │ │ ├── chat.js │ │ ├── index.html │ │ ├── script.js │ │ └── style.css └── server │ ├── app.json │ ├── index.js │ ├── package-lock.json │ └── package.json ├── ssr-react ├── app.js ├── build │ └── bundle.js ├── client │ └── index.js ├── package.json ├── public │ └── bundle.js ├── src │ ├── home.js │ ├── index.css │ ├── router.js │ ├── routers.js │ └── text.js ├── webpack.base.js ├── webpack.client.js └── webpack.server.js ├── swifts └── Wheel3DView.swift ├── swiper ├── index.min.ts ├── index.ts └── sdk │ ├── index.ts │ └── plugins │ ├── autoPlay.ts │ └── loopPlugin.ts ├── visualization-selection ├── dom.js ├── index.html ├── index.js ├── style.css ├── utils.js └── xpath.js ├── vue+jquery数学公式编辑 ├── README.md ├── js │ ├── data-tool.js │ ├── jquery-1.4.4.min.js │ └── uuid.js └── 数学公式.html ├── word-cloud ├── README.md ├── index.js ├── index.json ├── index.wxml ├── index.wxss ├── wordcloud.js └── wrod-cloud.js ├── wx-set-appid ├── package.json └── wx-config.js ├── wxchart ├── .idea │ ├── codeStyles │ │ └── codeStyleConfig.xml │ ├── modules.xml │ ├── vcs.xml │ ├── workspace.xml │ └── wxchart.iml ├── d3.min.js ├── drawutil.js ├── scalelinear.js ├── scaleordinal.js ├── scalepie.js ├── wxcharts-min.js └── wxcharts.js ├── zotero ├── LXGWWenKai-Regular.ttf ├── config.json ├── server.py └── zotero-pdf-2-zh.xpi └── 设计模式 ├── 创建模式 ├── abstractFactory.js ├── prototype.js ├── simpleFactory.js └── singleton.js ├── 结构模式 ├── adapter.js ├── bridge.js ├── builder.js ├── composite.js ├── decorator.js ├── facade.js ├── flyweight.js └── proxy.js └── 行为模式 ├── command.js ├── iterator.js ├── mediator.js ├── memento.js ├── observer.js ├── responsibility.js ├── state.js ├── strategy.js ├── template.js └── visitor.js /.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | package-lock.json 3 | node_modules 4 | */translated/** 5 | .DS_Store 6 | pnpm-lock.yaml 7 | __pycache__ 8 | dist 9 | yarn.lock 10 | pyRTC/models/asr 11 | pyRTC/models/tts 12 | __pycache__ 13 | .env 14 | pyRTC/**/*.wav 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "diffEditor.ignoreTrimWhitespace": false, 3 | "editor.tabSize": 2, 4 | "editor.detectIndentation": false, 5 | "liveServer.settings.port": 5503 6 | } -------------------------------------------------------------------------------- /Color/README.md: -------------------------------------------------------------------------------- 1 | 1. 引用 2 | 2. 定义方法: 3 | 4 | function enterRGB2(s) { 5 | 6 | if (s && s.match(/^\s*[0-9a-fA-F]{6}\s*$/)) { 7 | var r = hex2dec(s.substring(0,2)) 8 | var g = hex2dec(s.substring(2,4)); 9 | var b = hex2dec(s.substring(4,6)); 10 | var rgb = new RGB(r,g,b); 11 | Palette.setScheme('m1') 12 | var hsv = ColorWheel.getColorByRGB(rgb); 13 | Palette.setHSV(hsv); 14 | 15 | } 16 | } 17 | } 18 | 3. 使用 19 | enterRGB2('FF0000') 20 | 21 | ps: 22 | setScheme: 23 | 参数: m1 24 | 返回: Palette.Primary 主色 25 | 26 | 参数: m2 27 | 返回: Palette.Primary 主色 28 | Palette.Compl 互补色 29 | 30 | 参数: m3 31 | 返回: Palette.Primary 主色 32 | Palette.Sec1 辅助色 33 | Palette.Sec2 辅助色 34 | 35 | 36 | 参数: m4 37 | 返回: Palette.Primary 主色 38 | Palette.Sec1 辅助色 39 | Palette.Sec2 辅助色 40 | Palette.Compl 互补色 41 | 42 | 参数: m5 43 | 返回: Palette.Primary 主色 44 | Palette.Sec1 辅助色 45 | Palette.Sec2 辅助色 46 | 47 | 参数: m6 48 | 返回: Palette.Primary 主色 49 | Palette.Sec1 辅助色 50 | Palette.Sec2 辅助色 51 | Palette.Compl 互补色 52 | -------------------------------------------------------------------------------- /DemoQuartz/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /DemoQuartz/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/DemoQuartz/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /DemoQuartz/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /DemoQuartz/Configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /DemoQuartz/demoquart.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /DemoQuartz/generatorConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 17 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 35 |
36 | 37 | 38 |
39 |
-------------------------------------------------------------------------------- /DemoQuartz/src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.quartz.*; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 9 | 10 | @SpringBootApplication 11 | 12 | @MapperScan("com.example.demo.dao.mapper") 13 | public class DemoApplication extends WebMvcConfigurerAdapter{ 14 | 15 | public static void main(String[] args) throws SchedulerException{ 16 | SpringApplication.run(DemoApplication.class, args); 17 | System.out.print("开始"); 18 | // // 创建一个JobDetail实例 19 | // JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class) 20 | // // 指定JobDetail的名称和组名称 21 | // .withIdentity("job1", "group1").build(); 22 | // 23 | // // 创建一个CronTrigger,规定Job每隔一秒执行一次 24 | // CronTrigger trigger = TriggerBuilder.newTrigger() 25 | // // 指定Trigger名称和组名称 26 | // .startNow().withIdentity("trigger1", "group1") 27 | // // 设置cron运行规则,定义每秒执行一次 28 | // .withSchedule(CronScheduleBuilder.cronSchedule("*/2 * * * * ?")).build(); 29 | // // 得到Scheduler调度器实例 30 | // Scheduler scheduler = new StdSchedulerFactory().getScheduler(); 31 | // scheduler.scheduleJob(jobDetail, trigger); // 绑定JobDetail和Trigger 32 | // scheduler.start(); // 开始任务调度 33 | 34 | } 35 | // 跨域 36 | @Override 37 | public void addCorsMappings(CorsRegistry registry) { 38 | 39 | registry.addMapping("/**") 40 | .allowCredentials(true) 41 | .allowedHeaders("*") 42 | .allowedOrigins("*") 43 | .allowedMethods("*"); 44 | 45 | } 46 | 47 | 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /DemoQuartz/src/main/java/com/example/demo/jobs/QuartzJob.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.jobs; 2 | 3 | 4 | import org.quartz.*; 5 | import org.quartz.Job; 6 | import org.quartz.impl.StdSchedulerFactory; 7 | 8 | import java.text.SimpleDateFormat; 9 | import java.util.Date; 10 | 11 | public class QuartzJob implements Job{ 12 | 13 | @Override 14 | public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { 15 | // 任务逻辑代码 16 | SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 17 | System.out.print("QuartzJob" + df.format(new Date())); 18 | System.out.println(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /DemoQuartz/src/main/java/com/example/demo/jobs/QuartzJobTwo.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.jobs; 2 | 3 | 4 | import org.quartz.Job; 5 | import org.quartz.JobExecutionContext; 6 | import org.quartz.JobExecutionException; 7 | 8 | import java.text.SimpleDateFormat; 9 | import java.util.Date; 10 | 11 | public class QuartzJobTwo implements Job{ 12 | 13 | @Override 14 | public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { 15 | // 任务逻辑代码 16 | SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 17 | System.out.print("QuartzJobTwo" + df.format(new Date())); 18 | System.out.println(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /DemoQuartz/src/main/java/com/example/demo/requestparam/QuartzRequest.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.requestparam; 2 | 3 | import jdk.nashorn.internal.objects.annotations.Getter; 4 | import jdk.nashorn.internal.objects.annotations.Setter; 5 | 6 | 7 | public class QuartzRequest { 8 | private String triggerName; 9 | private String triggerGroupName; 10 | private String cron; 11 | 12 | public String getTriggerName() { 13 | return triggerName; 14 | } 15 | 16 | public void setTriggerName(String triggerName) { 17 | this.triggerName = triggerName; 18 | } 19 | 20 | public String getTriggerGroupName() { 21 | return triggerGroupName; 22 | } 23 | 24 | public void setTriggerGroupName(String triggerGroupName) { 25 | this.triggerGroupName = triggerGroupName; 26 | } 27 | 28 | public String getCron() { 29 | return cron; 30 | } 31 | 32 | public void setCron(String cron) { 33 | this.cron = cron; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /DemoQuartz/src/main/java/com/example/demo/uitl/BaseControuller.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.uitl; 2 | 3 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 4 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 5 | 6 | public class BaseControuller extends WebMvcConfigurerAdapter { 7 | @Override 8 | public void addCorsMappings(CorsRegistry registry) { 9 | 10 | registry.addMapping("/**") 11 | .allowCredentials(true) 12 | .allowedHeaders("*") 13 | .allowedOrigins("*") 14 | .allowedMethods("*"); 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /DemoQuartz/src/main/java/com/example/demo/uitl/BaseResponse.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.uitl; 2 | 3 | /** 4 | * Response 基础类 5 | * 6 | * @author HJR UPDATRE DATE 2017/12/11 7 | * @param 8 | */ 9 | public class BaseResponse { 10 | /** 11 | * 业务操作成功 12 | */ 13 | private static final Integer RESPONSE_STATUS_CODE_SUCCESS = 200; 14 | 15 | /** 16 | * 业务操作成功消息 17 | */ 18 | private static final String RESPONSE_STATUS_MSG_SUCCESS = "success"; 19 | private Integer statusCode; 20 | private String statusMsg; 21 | private T responseData; 22 | 23 | public BaseResponse() { 24 | this.statusCode = RESPONSE_STATUS_CODE_SUCCESS; 25 | this.statusMsg = RESPONSE_STATUS_MSG_SUCCESS; 26 | } 27 | 28 | public Integer getStatusCode() { 29 | return statusCode; 30 | } 31 | 32 | public void setStatusCode(Integer statusCode) { 33 | this.statusCode = statusCode; 34 | } 35 | 36 | public String getStatusMsg() { 37 | return statusMsg; 38 | } 39 | 40 | public void setStatusMsg(String statusMsg) { 41 | this.statusMsg = statusMsg; 42 | } 43 | 44 | public T getResponseData() { 45 | return responseData; 46 | } 47 | 48 | public void setResponseData(T responseData) { 49 | this.responseData = responseData; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /DemoQuartz/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.resources.static-locations=classpath:/target/classes 2 | spring.mvc.static-path-pattern=/** 3 | -------------------------------------------------------------------------------- /DemoQuartz/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | #激活哪一个环境的配置文件 2 | #公共配置 3 | spring: 4 | profiles: 5 | active: dev 6 | application: 7 | name: backservice 8 | jackson: 9 | date-format: yyyy-MM-dd HH:mm:ss 10 | time-zone: GMT+8 11 | datasource: 12 | password: 123456 13 | driver-class-name: com.mysql.jdbc.Driver 14 | url: "jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true" 15 | username: root 16 | server: 17 | port: 8200 18 | connectionTimeout: 10000 19 | maxConnections: 1000 20 | http: 21 | multipart: 22 | maxRequestSize: 1000Mb 23 | maxFileSize: 100Mb 24 | server: 25 | port: 8200 26 | connection-timeout: 3000 27 | 28 | mybatis: 29 | mapper-locations: classpath:mapper/*.xml 30 | type-aliases-package: com.example.demo.dao.pojo 31 | 32 | -------------------------------------------------------------------------------- /DemoQuartz/src/main/resources/mybatis-config.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/DemoQuartz/src/main/resources/mybatis-config.xml -------------------------------------------------------------------------------- /DemoQuartz/src/main/resources/spring-mybatis.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/DemoQuartz/src/main/resources/spring-mybatis.xml -------------------------------------------------------------------------------- /DemoQuartz/src/test/java/com/example/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /FuncJsRay/WebWork.js: -------------------------------------------------------------------------------- 1 | 2 | class WebWork { 3 | /** 4 | * @param {*} workPath web work js 路径 5 | * @param {*} timeOut 运行时长,超出结束进程 6 | */ 7 | constructor(workPath, timeOut) { 8 | this.status = false 9 | this.timeOut = timeOut ? timeOut : 10 10 | this.onMsg = null 11 | if (window.Worker) { 12 | this.worker = new Worker( workPath ? workPath : 'web_work.js'); 13 | this.worker.onmessage = (event) => { 14 | this.worker.terminate(); 15 | this.status = true 16 | if (typeof(this.onMsg) === 'function') { 17 | this.onMsg({code: '200', result: event }) 18 | } 19 | } 20 | this.worker.onerror = (event) => { 21 | this.worker.terminate(); 22 | this.status = true 23 | if (typeof(this.onMsg) === 'function') { 24 | this.onMsg({code: '202', result: event }) 25 | } 26 | }; 27 | } else { 28 | console.log('Your browser doesn\'t support web workers.') 29 | } 30 | } 31 | /** 32 | * 运行时间限制 33 | * @param {*} nowTime 34 | * @param {*} timeOut 35 | */ 36 | thanRunTime(nowTime, timeOut) { 37 | if ((new Date().getTime() - nowTime) / 1000 < timeOut && !this.status) { 38 | requestAnimationFrame(()=> { 39 | this.thanRunTime(nowTime, timeOut) 40 | }) 41 | } else { 42 | this.status = false 43 | this.worker.terminate(); 44 | if (typeof(this.onMsg) === 'function' && (new Date().getTime() - nowTime) / 1000 > timeOut) { 45 | console.error('run timeout!!', this.worker) 46 | this.onMsg({code: '201', result: { msg: 'run timeout!!'} }) 47 | } 48 | } 49 | } 50 | sendMessage(msg, callBack){ 51 | const runTimes = new Date().getTime() 52 | this.worker.postMessage( {data: Object.assign({}, msg), times: runTimes }); 53 | this.thanRunTime(runTimes, this.timeOut) 54 | if (typeof(callBack) === 'function') { 55 | this.onMsg = callBack 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /FuncJsRay/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /FuncJsRay/index.js: -------------------------------------------------------------------------------- 1 | function runWebWork() { 2 | new WebWork().sendMessage({ 3 | func: "hello", 4 | parmas: {} 5 | }, (res)=> { 6 | console.log(res) 7 | }) 8 | } -------------------------------------------------------------------------------- /FuncJsRay/web_work.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | importScripts("Rx.js"); 3 | onmessage = function (evt){ 4 | const msgData = evt.data;//通过evt.data获得发送来的数据 5 | console.time() 6 | const result = new Function('data', `${msgData.func ? '' : msgData.func}`)(msgData.params ? msgData.params : {}) 7 | console.log(result) 8 | console.timeEnd() 9 | postMessage(result);//将获取到的数据发送会主线程 10 | } 11 | })() 12 | 13 | -------------------------------------------------------------------------------- /JavaHttpTool/README.md: -------------------------------------------------------------------------------- 1 | https://blog.csdn.net/weixin_42429220/article/details/109177896 2 | 3 | -------------------------------------------------------------------------------- /Js-Fuck-Demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page Title 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /NodeDuanDian/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodeduandian", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "express": "^4.17.1" 14 | }, 15 | "dependencies": { 16 | "formidable": "^1.2.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WorkNotes 2 | 工具代码目录: 3 | 1. DemoQuartz ---- spring 自定义定时任务(添加 删除 修改) 4 | 2. exportExecl ---- 前端导出execl 表格 5 | 3. html5-Qrcode ---- 前端扫码 6 | 4. htmlExportPDF --- 前端将页面导出pdf文件 7 | 5. JavaHttpTool --- maven集成的http请求工具类 8 | 6. mobileEvent --- 前端手机的触摸事件 9 | 7. socketIoDemo --- 使用 socketIo js 实现的聊天页面 10 | 8. echartBmap --- echart百度地图 飞线图 11 | 9. HT FOR WEB --- 自定义菜单 12 | 10. Color --- 计算颜色的互补、辅助色。 13 | 11. vue+jquery --- 数学公式编辑。 14 | 12. NodeDuanDian --- Node服务断点续传 15 | 13. Wx-QianMing --- 微信小程序canvas签名 16 | 14. Wx-美团日期 ---- 微信小程序仿美团日期组件 17 | 15. react-web-pro-master ---- react项目模板 18 | 16. word-cloud --- 微信小程序词云组件 19 | 17. wx-set-appid --- 微信小程序修改appid工具 20 | 18. web-note-canvas --- 谷歌浏览器插件笔记 21 | 19. FuncJsRay --- eval 运行时间限制 22 | 20. go_makemask --- go 图片添加水印 23 | 21. online_code--基于iframe在线运行代码 24 | 22. data-proxy--基于node的http代理抓包 25 | 23. visualization-selection--- 可视化埋点圈选功能 26 | 24. emojimixer --- 表情包混合 27 | 25. 设计模式---js常用设计模式 28 | 26. ssr-react --- react服务器渲染基本原理 29 | 27. node-websocket --- 实现一个websocket 协议服务 30 | 28. rrweb-demo --- 基于虚拟dom录屏网页 31 | 29. protobf-demo --- 基于node的protobf使用 32 | 30. swiper -- 简易版swiper【SDK 中支持plugin注入】 33 | 31. wheel3DView -- swift 3d 加载动画 34 | 32. SparkleUpdate -- 自定义Sparkle更新窗口 35 | 33. SherpaOnnx -- SherpaOnnx swift 模型引用文件 36 | 34. mcp-weather-server -- claude mcp 天气服务 37 | 35. zotero -- 基于zotero的pdf中英翻译 38 | 36. mcp-weather -- gemini MCP 服务端处理 39 | 37. pyRAG -- 基于python简单实现RAG 40 | 38. i18n-processor -- 国际化处理工具、结合[voerka-i18n](https://zhangfisher.github.io/voerka-i18n/) 41 | 39. pyRTC -- 基于python实现的实时语音识别、语音合成LLM + ASR + TTS (SherpaOnnx) 42 | 40. mobile_table -- 支持移动端合并单元格的表格组件 43 | -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.detectIndentation": false, 3 | "editor.tabSize": 2, 4 | "editor.formatOnPaste": false, 5 | "editor.formatOnSave": false 6 | } -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Chrome Plug 7 | 8 | 9 | 10 |

这是一个Chrome插件

11 | 26 | 27 | -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/background.js: -------------------------------------------------------------------------------- 1 | console.log('background') -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/chromePlug.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/chromePlug.zip -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/img/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/img/icon/icon.png -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/img/popup/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/img/popup/arrow.png -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/img/popup/del.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/img/popup/del.png -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/img/popup/pen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/img/popup/pen.png -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/img/popup/remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/img/popup/remove.png -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/img/popup/select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/img/popup/select.png -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/img/popup/serial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/img/popup/serial.png -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/img/popup/sure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/img/popup/sure.png -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/img/popup/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/img/popup/text.png -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/js/src/content-msg.js: -------------------------------------------------------------------------------- 1 | chrome.runtime.onMessage.addListener(async (request, sender, sendResponse)=>{ 2 | const cmdVal = request.cmd 3 | if(cmdVal === 'create') { 4 | console.log('userInfo===', ) 5 | const userInfo = request.userInfo 6 | getAccount('set', userInfo.account) 7 | getToken('set',userInfo.token) 8 | getLogin('set', userInfo.login) 9 | // renderNotes(); 10 | renderHasData(); 11 | } else if (cmdVal === 'login') { 12 | 13 | 14 | } 15 | // return true; 16 | }); 17 | 18 | -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/js/src/data.js: -------------------------------------------------------------------------------- 1 | // let cacheData = null -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/js/src/fabrictool/config-data.js: -------------------------------------------------------------------------------- 1 | const g_fc_drawWidth = 2; //笔触宽度 2 | let g_fc_color = "#E34F51"; //画笔颜色 3 | let g_fc_drawingObject = null; //当前绘制对象 4 | let g_fc_moveCount = 1; //绘制移动计数器 5 | let g_fc_doDrawing = false; // 绘制状态 6 | let g_fc_mouseFrom = {} 7 | let g_fc_mouseTo = {} 8 | let g_fc_drawType = null 9 | let g_fc_canvasObjectIndex = 0 10 | let g_fc_textbox = null 11 | let g_fc_out_drawtypes = ['text', 'serial'] 12 | let g_fc_serial_num = 0 -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/js/src/fabrictool/draws/arrow.js: -------------------------------------------------------------------------------- 1 | //绘制箭头方法 2 | function drawArrow(fromX, fromY, toX, toY, theta, headlen) { 3 | theta = typeof theta != "undefined" ? theta : 20; 4 | headlen = typeof theta != "undefined" ? headlen : 10; 5 | // 计算各角度和对应的P2,P3坐标 6 | var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI, 7 | angle1 = (angle + theta) * Math.PI / 180, 8 | angle2 = (angle - theta) * Math.PI / 180, 9 | topX = headlen * Math.cos(angle1), 10 | topY = headlen * Math.sin(angle1), 11 | botX = headlen * Math.cos(angle2), 12 | botY = headlen * Math.sin(angle2); 13 | var arrowX = fromX - topX, 14 | arrowY = fromY - topY; 15 | var path = " M " + fromX + " " + fromY; 16 | path += " L " + toX + " " + toY; 17 | arrowX = toX + topX; 18 | arrowY = toY + topY; 19 | path += " M " + arrowX + " " + arrowY; 20 | path += " L " + toX + " " + toY; 21 | arrowX = toX + botX; 22 | arrowY = toY + botY; 23 | path += " L " + arrowX + " " + arrowY; 24 | return path; 25 | } 26 | 27 | function creatArrow(canvas, mouseFrom, mouseTo, color, drawWidth) { 28 | return new fabric.Path(drawArrow(mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y, 12, 12), { 29 | stroke: color, 30 | fill: "rgba(255,255,255,0)", 31 | hasControls: false, 32 | strokeWidth: drawWidth 33 | }); 34 | } -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/js/src/fabrictool/draws/index.js: -------------------------------------------------------------------------------- 1 | const DRAW_DATA = { 2 | arrow: creatArrow, 3 | text: creatText, 4 | serial: drawSerial, 5 | } 6 | function creatText(canvas, mouseFrom, mouseTo, color, drawWidth) { 7 | if (g_fc_textbox) return null 8 | g_fc_textbox = new fabric.Textbox("", { 9 | left: mouseFrom.x - 60, 10 | top: mouseFrom.y - 20, 11 | width: 150, 12 | fontSize: 24, 13 | borderColor: "#FF0000", 14 | fill: color, 15 | hasControls: false, 16 | editingBorderColor: "#FF0000" 17 | }); 18 | canvas.add(g_fc_textbox); 19 | g_fc_textbox.enterEditing(); 20 | g_fc_textbox.hiddenTextarea.focus(); 21 | return null 22 | } -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/js/src/fabrictool/index.js: -------------------------------------------------------------------------------- 1 | 2 | async function initFabricCanvas(){ 3 | //初始化画板 4 | g_fabric_canvas = new fabric.Canvas('hz-note_canvas', { 5 | isDrawingMode: true, 6 | skipTargetFind: true, 7 | selectable: false, 8 | selection: false, 9 | hasControls: false, 10 | containerClass: 'hz-tools_content', 11 | }); 12 | initSetting(g_fabric_canvas) 13 | handleMouseDown(g_fabric_canvas); 14 | handleMouseUp(g_fabric_canvas, drawing) 15 | handleMouseMove(g_fabric_canvas, drawing) 16 | handleSelectionCreated(g_fabric_canvas) 17 | const cacheData = await checkHasData() 18 | if (cacheData) { 19 | g_fabric_canvas.loadFromJSON(JSON.parse(cacheData) , ()=> { 20 | requestAnimationFrame(()=> { 21 | createSerialByInitCache(g_fabric_canvas) 22 | }) 23 | }) 24 | } 25 | } 26 | 27 | 28 | function drawing(canvas) { 29 | console.log(g_fc_drawType) 30 | if (g_fc_drawingObject ) { 31 | canvas.remove(g_fc_drawingObject); 32 | } 33 | let canvasObject = null; 34 | if (DRAW_DATA[g_fc_drawType]) { 35 | canvasObject = DRAW_DATA[g_fc_drawType](g_fabric_canvas, g_fc_mouseFrom, g_fc_mouseTo, g_fc_color, g_fc_drawWidth) 36 | } 37 | if (canvasObject) { 38 | canvas.add(canvasObject); //.setActiveObject(canvasObject) 39 | if( ['arrow'].indexOf(g_fc_drawType) !== -1) { 40 | g_fc_drawingObject = canvasObject; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/js/src/fabrictool/setting.js: -------------------------------------------------------------------------------- 1 | 2 | function initSetting(canvas){ 3 | canvas.freeDrawingBrush.color = g_fc_color; //设置自由绘颜色 4 | canvas.freeDrawingBrush.width = g_fc_drawWidth; 5 | } 6 | function setBrushColor(canvas, color) { 7 | g_fc_color = color 8 | canvas.freeDrawingBrush.color = g_fc_color; 9 | } -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/js/src/tool/element.js: -------------------------------------------------------------------------------- 1 | // 创建一个img 2 | function createImg(params = {}){ 3 | const imgURL = chrome.runtime.getURL(params.url); 4 | const image = $('') 5 | image.attr('src', imgURL) 6 | image.attr(params) 7 | return image 8 | } 9 | function createDiv(params = {}){ 10 | const divEl = $('
') 11 | divEl.attr(params) 12 | return divEl; 13 | } 14 | function createInput(params = {}){ 15 | const inputEl = $('') 16 | inputEl.attr(params) 17 | return inputEl 18 | } -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/js/src/tool/event.js: -------------------------------------------------------------------------------- 1 | function initEvent() { 2 | $('#note-btn').on('click', (event)=>{ 3 | if(event && event.target) { 4 | const targetEl = $(event.target) 5 | const typeVal = targetEl.data('type') 6 | if (!typeVal || typeVal === 'other') { 7 | return 8 | } else { 9 | if (g_fabric_canvas && g_noteStatus) { 10 | if (g_unactives.indexOf(typeVal) === -1) { 11 | $('.hz-opt-img').removeClass('ht-active') 12 | $(`.hz-${typeVal}`).addClass('ht-active') 13 | } 14 | if (g_fc_textbox) { 15 | g_fc_textbox.exitEditing(); 16 | g_fc_textbox = null; 17 | } 18 | handleOpt(typeVal) 19 | } 20 | } 21 | } 22 | }) 23 | 24 | $('#hz-brush-color').on('change', function(){ 25 | const color = $(this).val() 26 | setBrushColor( g_fabric_canvas, color) 27 | if (g_fc_textbox) { 28 | g_fc_textbox.setOptions({fill: color, editingBorderColor: color,borderColor: color,}) 29 | } 30 | }) 31 | 32 | } -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "Notes Canvas", 4 | "version": "1.3.0", 5 | "description": "基于canvas的线上notes", 6 | "icons": { 7 | "16": "img/icon/icon.png", 8 | "48": "img/icon/icon.png", 9 | "128": "img/icon/icon.png" 10 | }, 11 | "background": { 12 | "service_worker": "background.js" 13 | }, 14 | "action": { 15 | "default_icon": "img/icon/icon.png", 16 | "default_title": "这是一个示例Chrome插件", 17 | "default_popup": "popup.html" 18 | }, 19 | "content_scripts": [ 20 | { 21 | "matches": [ 22 | "" 23 | ], 24 | "js": [ 25 | "js/src/data.js", 26 | "js/libs/axio.js", 27 | "js/libs/html2canvas.js", 28 | "js/libs/fabric.min.js", 29 | "js/libs/jquery.min.js", 30 | "js/src/global-data.js", 31 | "js/src/fabrictool/config-data.js", 32 | "js/src/fabrictool/draws/arrow.js", 33 | "js/src/fabrictool/draws/serial.js", 34 | "js/src/fabrictool/draws/index.js", 35 | "js/src/fabrictool/setting.js", 36 | "js/src/fabrictool/event.js", 37 | "js/src/fabrictool/index.js", 38 | "js/src/tool/element.js", 39 | "js/src/tool/event.js", 40 | "js/src/tool/index.js", 41 | "js/src/tools.js", 42 | "js/src/main.js", 43 | "js/src/content-msg.js" 44 | ], 45 | "css": [ 46 | "css/hz-content.css" 47 | ], 48 | "run_at": "document_end" 49 | } 50 | ], 51 | "permissions": [ 52 | "activeTab" 53 | ], 54 | "web_accessible_resources": [ 55 | { 56 | "resources": [ 57 | "/img/popup/*.png" 58 | ], 59 | "matches": [""], 60 | "extension_ids": [] 61 | } 62 | ] 63 | } -------------------------------------------------------------------------------- /WebPageNotes/chromePlug/note_canvas.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/chromePlug/note_canvas.zip -------------------------------------------------------------------------------- /WebPageNotes/codeSign.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/codeSign.zip -------------------------------------------------------------------------------- /WebPageNotes/codeSign/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.detectIndentation": false, 3 | "editor.tabSize": 2, 4 | "editor.formatOnPaste": true, 5 | "editor.formatOnSave": true 6 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Chrome Plug 8 | 9 | 10 | 11 | 12 |

xxx

13 | 14 | 15 | -------------------------------------------------------------------------------- /WebPageNotes/codeSign/background.js: -------------------------------------------------------------------------------- 1 | console.log(chrome) 2 | chrome.action.onClicked.addListener(function(tab) { 3 | sendMessageToContentScript({cmd:'wtc_cmd', value: 'yeah'}, function(response){ 4 | console.log('来自content的回复:'+response); 5 | }); 6 | }); 7 | 8 | function sendMessageToContentScript(message, callback){ 9 | chrome.tabs.query({active: true, currentWindow: true}, function(tabs){ 10 | chrome.tabs.sendMessage(tabs[0].id, message, function(response) 11 | { 12 | if(callback) callback(response); 13 | }); 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /WebPageNotes/codeSign/css/atom-one-dark.min.css: -------------------------------------------------------------------------------- 1 | .hljs { 2 | display: block; 3 | overflow-x: auto; 4 | padding: 0.5em; 5 | color: #abb2bf; 6 | background: #282c34 7 | } 8 | 9 | .hljs-comment, 10 | .hljs-quote { 11 | color: #5c6370; 12 | font-style: italic 13 | } 14 | 15 | .hljs-doctag, 16 | .hljs-keyword, 17 | .hljs-formula { 18 | color: #c678dd 19 | } 20 | 21 | .hljs-section, 22 | .hljs-name, 23 | .hljs-selector-tag, 24 | .hljs-deletion, 25 | .hljs-subst { 26 | color: #e06c75 27 | } 28 | 29 | .hljs-literal { 30 | color: #56b6c2 31 | } 32 | 33 | .hljs-string, 34 | .hljs-regexp, 35 | .hljs-addition, 36 | .hljs-attribute, 37 | .hljs-meta-string { 38 | color: #98c379 39 | } 40 | 41 | .hljs-built_in, 42 | .hljs-class .hljs-title { 43 | color: #e6c07b 44 | } 45 | 46 | .hljs-attr, 47 | .hljs-variable, 48 | .hljs-template-variable, 49 | .hljs-type, 50 | .hljs-selector-class, 51 | .hljs-selector-attr, 52 | .hljs-selector-pseudo, 53 | .hljs-number { 54 | color: #d19a66 55 | } 56 | 57 | .hljs-symbol, 58 | .hljs-bullet, 59 | .hljs-link, 60 | .hljs-meta, 61 | .hljs-selector-id, 62 | .hljs-title { 63 | color: #61aeee 64 | } 65 | 66 | .hljs-emphasis { 67 | font-style: italic 68 | } 69 | 70 | .hljs-strong { 71 | font-weight: bold 72 | } 73 | 74 | .hljs-link { 75 | text-decoration: underline 76 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/css/wtechtec-loading.css: -------------------------------------------------------------------------------- 1 | .hz-loading_content { 2 | width: 100%; 3 | height: 100%; 4 | position: fixed; 5 | background: rgba(255, 255, 255, 0.8); 6 | z-index: 99999999; 7 | left: 0; 8 | top: 0; 9 | display: none; 10 | } 11 | 12 | .loading { 13 | width: 150px; 14 | height: 15px; 15 | margin: 0 auto; 16 | margin-top: 100px; 17 | text-align: center; 18 | } 19 | 20 | .loading span { 21 | display: inline-block; 22 | width: 15px; 23 | height: 100%; 24 | margin-right: 5px; 25 | background: lightgreen; 26 | -webkit-animation: load 1.04s ease infinite; 27 | } 28 | 29 | .loading span:last-child { 30 | margin-right: 0px; 31 | } 32 | 33 | @-webkit-keyframes load { 34 | 0% { 35 | opacity: 1; 36 | -webkit-transform: scale(1.2); 37 | } 38 | 39 | 100% { 40 | opacity: .2; 41 | -webkit-transform: scale(.2); 42 | } 43 | } 44 | 45 | .loading span:nth-child(1) { 46 | -webkit-animation-delay: 0.13s; 47 | } 48 | 49 | .loading span:nth-child(2) { 50 | -webkit-animation-delay: 0.26s; 51 | } 52 | 53 | .loading span:nth-child(3) { 54 | -webkit-animation-delay: 0.39s; 55 | } 56 | 57 | .loading span:nth-child(4) { 58 | -webkit-animation-delay: 0.52s; 59 | } 60 | 61 | .loading span:nth-child(5) { 62 | -webkit-animation-delay: 0.65s; 63 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/css/wtechtec.css: -------------------------------------------------------------------------------- 1 | .wtechtec-opt { 2 | width: 220px; 3 | position: fixed; 4 | top: 0; 5 | right: 35px; 6 | border: 1px solid #265CF0; 7 | display: flex; 8 | justify-content: space-between; 9 | align-items: center; 10 | z-index: 99999; 11 | text-align: center; 12 | cursor: pointer; 13 | background-color: #F5F6FA; 14 | display: none; 15 | } 16 | 17 | .wtechtec-opt-item { 18 | padding: 12px 4px; 19 | flex: 1; 20 | } 21 | 22 | .wtechtec-opt-item:hover { 23 | color: #265CF0; 24 | background-color: rgba(38, 92, 240, 0.08); 25 | } 26 | 27 | .wtechtec-opt-item.active { 28 | color: #265CF0; 29 | background-color: rgba(38, 92, 240, 0.1); 30 | font-weight: bold; 31 | } 32 | 33 | .wtc-tools_content { 34 | position: absolute !important; 35 | top: 50px !important; 36 | left: 0 !important; 37 | user-select: none; 38 | z-index: 9999; 39 | outline: none; 40 | 41 | } 42 | 43 | .wtc_diaglog { 44 | position: fixed; 45 | z-index: 9999999; 46 | top: 50px; 47 | display: none; 48 | background-color: #f2f2f2; 49 | width: 650px; 50 | height: 750px; 51 | left: 50%; 52 | transform: translateX(-50%); 53 | padding: 10px; 54 | overflow-y: auto; 55 | } 56 | 57 | .btn_close { 58 | cursor: pointer; 59 | font-size: 16px; 60 | color: #666666; 61 | text-align: right; 62 | } 63 | 64 | .btn_close:hover { 65 | color: #265CF0; 66 | } 67 | 68 | .desc { 69 | font-size: 24px; 70 | font-weight: bold; 71 | color: #333333; 72 | } 73 | 74 | .CodeMirror-hints { 75 | z-index: 9999999999999999999999999999999; 76 | } 77 | 78 | #cm-complete-0 { 79 | z-index: 9999999999999999999999999999999; 80 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/img/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/WebPageNotes/codeSign/img/icon/icon.png -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/libs/codemirror/addon/show-hint.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-hints { 2 | position: absolute; 3 | z-index: 10; 4 | overflow: hidden; 5 | list-style: none; 6 | 7 | margin: 0; 8 | padding: 2px; 9 | 10 | -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 11 | -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 12 | box-shadow: 2px 3px 5px rgba(0,0,0,.2); 13 | border-radius: 3px; 14 | border: 1px solid silver; 15 | 16 | background: white; 17 | font-size: 90%; 18 | font-family: monospace; 19 | 20 | max-height: 20em; 21 | overflow-y: auto; 22 | } 23 | 24 | .CodeMirror-hint { 25 | margin: 0; 26 | padding: 0 4px; 27 | border-radius: 2px; 28 | white-space: pre; 29 | color: black; 30 | cursor: pointer; 31 | } 32 | 33 | li.CodeMirror-hint-active { 34 | background: #08f; 35 | color: white; 36 | } 37 | -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/atom/format.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 统一颜色的值 3 | * @param {*} value 4 | * @returns 5 | */ 6 | function formatColor(value) { 7 | if (value && value.indexOf('#') === 0) { 8 | // 统一转成小写 9 | value = value.toLocaleLowerCase(); 10 | // #F2F => #FF22FF 11 | if (value.length === 4) { 12 | const valueSplits = value.substring(1).split(''); 13 | return `#${valueSplits[0]}${valueSplits[0]}${valueSplits[1]}${valueSplits[1]}${valueSplits[2]}${valueSplits[2]}`; 14 | } 15 | } 16 | return value; 17 | } 18 | /** 19 | * 统一content的值 20 | * @param {*} value 21 | * @returns 22 | */ 23 | function formatContent(value) { 24 | if (value) { 25 | return value.replace(/\s+/g, '').replace(/["|']/g, '"'); 26 | } 27 | return value; 28 | } 29 | 30 | /** 31 | * 统一将0rpx, 0px, 0Px, 0PX 转换 0 32 | * @param {*} value 33 | * @returns 34 | */ 35 | function formatZero(value) { 36 | if (value) { 37 | value = value.toLocaleLowerCase(); 38 | if (value === '0rpx' || value === '0px') return '0'; 39 | return value; 40 | } 41 | return value; 42 | } 43 | 44 | const PropFormat = { 45 | color: formatColor, 46 | background: formatColor, 47 | 'background-color': formatColor, 48 | content: formatContent, 49 | left: formatZero, 50 | right: formatZero, 51 | top: formatZero, 52 | bottom: formatZero, 53 | padding: formatZero, 54 | 'padding-top': formatZero, 55 | 'padding-bottom': formatZero, 56 | 'padding-left': formatZero, 57 | 'padding-right': formatZero, 58 | margin: formatZero, 59 | 'margin-left': formatZero, 60 | 'margin-right': formatZero, 61 | 'margin-top': formatZero, 62 | 'margin-bottom': formatZero, 63 | }; 64 | -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/fabrictool/config-data.js: -------------------------------------------------------------------------------- 1 | const g_fc_drawWidth = 2; //笔触宽度 2 | let g_fc_color = "rgba(38,92,240, 0.08)"; //画笔颜色 3 | let g_fc_drawingObject = null; //当前绘制对象 4 | let g_fc_moveCount = 1; //绘制移动计数器 5 | let g_fc_doDrawing = false; // 绘制状态 6 | let g_fc_mouseFrom = {} 7 | let g_fc_mouseTo = {} 8 | let g_fc_drawType = 'rect' 9 | let g_fc_canvasObjectIndex = 0 10 | let g_fc_textbox = null 11 | let g_fc_out_drawtypes = ['text', 'serial'] 12 | let g_fc_serial_num = 0 13 | let g_fc_currentSelectObject = null; 14 | let g_dom_id = 0 15 | -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/fabrictool/draws/arrow.js: -------------------------------------------------------------------------------- 1 | //绘制箭头方法 2 | function drawArrow(fromX, fromY, toX, toY, theta, headlen) { 3 | theta = typeof theta != "undefined" ? theta : 20; 4 | headlen = typeof theta != "undefined" ? headlen : 10; 5 | // 计算各角度和对应的P2,P3坐标 6 | var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI, 7 | angle1 = (angle + theta) * Math.PI / 180, 8 | angle2 = (angle - theta) * Math.PI / 180, 9 | topX = headlen * Math.cos(angle1), 10 | topY = headlen * Math.sin(angle1), 11 | botX = headlen * Math.cos(angle2), 12 | botY = headlen * Math.sin(angle2); 13 | var arrowX = fromX - topX, 14 | arrowY = fromY - topY; 15 | var path = " M " + fromX + " " + fromY; 16 | path += " L " + toX + " " + toY; 17 | arrowX = toX + topX; 18 | arrowY = toY + topY; 19 | path += " M " + arrowX + " " + arrowY; 20 | path += " L " + toX + " " + toY; 21 | arrowX = toX + botX; 22 | arrowY = toY + botY; 23 | path += " L " + arrowX + " " + arrowY; 24 | return path; 25 | } 26 | 27 | function creatArrow(canvas, mouseFrom, mouseTo, color, drawWidth) { 28 | return new fabric.Path(drawArrow(mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y, 12, 12), { 29 | stroke: color, 30 | fill: "rgba(255,255,255,0)", 31 | hasControls: false, 32 | strokeWidth: drawWidth 33 | }); 34 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/fabrictool/draws/index.js: -------------------------------------------------------------------------------- 1 | const DRAW_DATA = { 2 | arrow: creatArrow, 3 | rect: drawRect, 4 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/fabrictool/draws/rect.js: -------------------------------------------------------------------------------- 1 | // 绘制矩形 2 | function drawRect(canvas, mouseFrom, mouseTo, color, drawWidth) { 3 | // 计算矩形长宽 4 | let width = mouseFrom.x - mouseTo.x; 5 | let height = mouseFrom.y - mouseTo.y; 6 | let left = mouseFrom.x; 7 | let top = mouseFrom.y; 8 | if (width > 0) { 9 | left = mouseTo.x; 10 | } 11 | if (height > 0) { 12 | top = mouseTo.y; 13 | } 14 | // 创建矩形 对象 15 | let canvasObject = new fabric.Rect({ 16 | left, 17 | top, 18 | width: Math.abs(width), 19 | height: Math.abs(height), 20 | stroke: color, 21 | fill: color, 22 | strokeWidth: drawWidth, 23 | domId: String(g_dom_id), 24 | }); 25 | return canvasObject; 26 | } 27 | -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/form-view/dom.js: -------------------------------------------------------------------------------- 1 | function initFormDom() { 2 | const parentDiv = createDiv('form-content', 'wtc_form_content'); 3 | const formDom = $(FORM_TEMP.toString()); 4 | parentDiv.append(formDom); 5 | const freameDiv = createFragment(); 6 | const diaglogDom = $(CODE_TEMP.toString()); 7 | freameDiv.append(parentDiv); 8 | freameDiv.append(diaglogDom); 9 | $('body').append(freameDiv); 10 | setTimeout(()=> { 11 | g_form_style_editor || (g_form_style_editor = CodeMirror.fromTextArea(document.getElementById("wtc_style_content"), { 12 | extraKeys: {"Ctrl": "autocomplete"} 13 | })); 14 | g_form_after_editor || (g_form_after_editor = CodeMirror.fromTextArea(document.getElementById("wtc_after_content"), { 15 | extraKeys: {"Ctrl": "autocomplete"} 16 | })); 17 | }, 0); 18 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/form-view/event.js: -------------------------------------------------------------------------------- 1 | function initFormData() { 2 | if (!g_fc_currentSelectObject) return; 3 | const domId = g_fc_currentSelectObject.target.domId; 4 | let formData = g_form_data_map[domId]; 5 | if (formData) { 6 | $('#wtc_dom_id').val(formData.domId); 7 | $('#wtc_parent_id').val(formData.parentId); 8 | $('#wtc_class_name').val(formData.className); 9 | // $('#wtc_style_content').val(formData.style); 10 | $('#wtc_rank_num').val(formData.rankNum); 11 | // $('#wtc_after_content').val(formData.afterContent); 12 | g_form_style_editor && g_form_style_editor.setValue(formData.style); 13 | g_form_after_editor && g_form_after_editor.setValue(formData.afterContent); 14 | $('#wtc_view_content').val(formData.viewContent); 15 | } 16 | } 17 | function initFormEvent() { 18 | $('#wtc_save_form_btn').on('click', () => { 19 | $('#hz_loading').show(); 20 | const domId = $('#wtc_dom_id').val(); 21 | const formData = g_form_data_map[domId]; 22 | if (formData) { 23 | formData.parentId = $('#wtc_parent_id').val(); 24 | formData.className = $('#wtc_class_name').val(); 25 | formData.rankNum = $('#wtc_rank_num').val(); 26 | // formData.style = $('#wtc_style_content').val(); 27 | // formData.afterContent = $('#wtc_after_content').val(); 28 | g_form_style_editor.save(); 29 | g_form_after_editor.save(); 30 | g_form_style_editor && (formData.style = g_form_style_editor.getValue()); 31 | g_form_after_editor && (formData.afterContent = g_form_after_editor.getValue()); 32 | // console.log(g_form_style_editor.getValue()) 33 | // console.log(g_form_after_editor.getValue()) 34 | formData.viewContent = $('#wtc_view_content').val(); 35 | } 36 | setTimeout(() => { 37 | $('#hz_loading').hide(); 38 | }, 200); 39 | }) 40 | $('#wtc_close_btn').on('click', () => { 41 | $('.wtc_diaglog').hide(); 42 | }) 43 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/form-view/index.js: -------------------------------------------------------------------------------- 1 | function initForm() { 2 | initFormDom(); 3 | initFormEvent(); 4 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/form-view/temp: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Contact Form 4 | Please fill all the texts in the fields. 5 |

6 | 7 | 11 | 12 | 16 | 17 | 21 | 22 | 28 | 29 | 33 |
34 |
-------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/global.js: -------------------------------------------------------------------------------- 1 | let g_fabric_canvas = null; 2 | let g_making = false; 3 | let g_select_status = false; 4 | let g_form_data_map = {}; 5 | let g_form_style_editor = null; 6 | let g_form_after_editor = null; -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/main.js: -------------------------------------------------------------------------------- 1 | initRenderOpt() 2 | initForm() 3 | 4 | 5 | chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { 6 | // console.log(sender.tab ?"from a content script:" + sender.tab.url :"from the extension"); 7 | if (request.cmd == 'wtc_cmd') { 8 | $('.wtechtec-opt').css('display', 'flex'); 9 | } 10 | sendResponse('yeah') 11 | }); 12 | 13 | // console.log(html_beautify('', { indent_size: 2, space_in_empty_paren: true })); 14 | // console.log(css_beautify('.blue { color: blue;} ', { indent_size: 2, space_in_empty_paren: true })) -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/top-opt/config.js: -------------------------------------------------------------------------------- 1 | const OPT_DATAS = [ 2 | { 3 | id: 'wtc_make', 4 | className: 'wtechtec-opt-item', 5 | label: '开始制作', 6 | }, 7 | { 8 | id: 'wtc_select', 9 | className: 'wtechtec-opt-item', 10 | label: '选择' 11 | }, 12 | { 13 | id: 'wtc_save', 14 | className: 'wtechtec-opt-item', 15 | label: '生成' 16 | }, 17 | ] -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/top-opt/dom.js: -------------------------------------------------------------------------------- 1 | 2 | function createLoadingEl() { 3 | const loadingEl = createDiv('loading'); 4 | for (let i = 0; i < 5; i++) { 5 | loadingEl.append($('')) 6 | } 7 | const loadingContent = createDiv('hz-loading_content', 'hz_loading') 8 | loadingContent.append(loadingEl) 9 | return loadingContent; 10 | } 11 | 12 | function createCanvas() { 13 | const canvasEl = $('') 14 | const bodyEl = $('html') 15 | canvasEl.attr({ 16 | id: 'wtc_canvas', 17 | width: bodyEl.width() + 'px', 18 | height: bodyEl.height() + 'px', 19 | tabIndex: -1 20 | }) 21 | canvasEl.css({ 22 | display: 'none', 23 | }); 24 | return canvasEl; 25 | } 26 | 27 | function renderOptDom() { 28 | const parentDom = createDiv('wtechtec-opt', 'wtechtec_opt'); 29 | OPT_DATAS.forEach(item => { 30 | const itemDiv = createDiv(item.className, item.id) 31 | itemDiv.text(item.label); 32 | parentDom.append(itemDiv); 33 | }) 34 | const loadingEl = createLoadingEl(); 35 | const fargment = createFragment(); 36 | const canvasDiv = createCanvas(); 37 | fargment.append(parentDom); 38 | fargment.append(loadingEl); 39 | fargment.append(canvasDiv); 40 | $('body').append(fargment); 41 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/top-opt/event.js: -------------------------------------------------------------------------------- 1 | function initOptEvent() { 2 | $('#wtechtec_opt').on("click", (e) => { 3 | const targetDom = $(e.target); 4 | const id = targetDom.attr('id'); 5 | if (id === 'wtc_save') { 6 | createView(); 7 | return; 8 | } 9 | $('.wtechtec-opt-item.active').removeClass('active'); 10 | $('#hz_loading').show(); 11 | if (id === 'wtc_make') { 12 | g_fc_drawType = 'rect'; 13 | g_fc_doDrawing = true 14 | $('#wtc_form_content').hide(); 15 | if (g_fabric_canvas) { 16 | g_fc_mouseFrom = {}; 17 | g_making = !g_making; 18 | targetDom.text(g_making ? '暂停制作' : '开始制作'); 19 | g_making ? $('.wtc-tools_content').show() : $('.wtc-tools_content').hide(); 20 | g_fabric_canvas.selection = false; 21 | g_fabric_canvas.skipTargetFind = true; 22 | g_fabric_canvas.selectable = false; 23 | g_fabric_canvas.discardActiveObject().renderAll(); //清楚选中框 24 | } else { 25 | g_making = true; 26 | targetDom.text('暂停制作'); 27 | initFabricCanvas(); 28 | } 29 | } else if (id === 'wtc_select') { 30 | g_select_status = true; 31 | g_making = false; 32 | g_fc_drawType = null; 33 | $('#wtc_make').text('开始制作'); 34 | g_fabric_canvas.selection = true; 35 | g_fabric_canvas.skipTargetFind = false; 36 | g_fabric_canvas.selectable = true; 37 | } 38 | requestAnimationFrame(() => { 39 | if (!(id === 'wtc_make' && !g_making)) { 40 | targetDom.addClass('active'); 41 | } 42 | $('#hz_loading').hide(); 43 | }) 44 | }); 45 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/top-opt/index.js: -------------------------------------------------------------------------------- 1 | function initRenderOpt() { 2 | renderOptDom(); 3 | initOptEvent(); 4 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/units/color.js: -------------------------------------------------------------------------------- 1 | function randomNum(min, max) { 2 | return min + Math.random() * (max - min); 3 | } 4 | 5 | function randomColor() { 6 | return `rgba(${randomNum(38, 80)}, ${randomNum(92, 125)}, ${randomNum(200, 255)},0.5)`; 7 | } 8 | -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/units/dom-ui.js: -------------------------------------------------------------------------------- 1 | // 创建一个img 2 | function createImg(url) { 3 | var imgURL = chrome.extension.getURL(url); 4 | let image = $('') 5 | image.attr('src', imgURL) 6 | return image 7 | } 8 | function uuid() { 9 | var s = []; 10 | var hexDigits = "0123456789abcdef"; 11 | for (var i = 0; i < 36; i++) { 12 | s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); 13 | } 14 | s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 15 | s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 16 | s[8] = s[13] = s[18] = s[23] = "-"; 17 | 18 | var uuid = s.join(""); 19 | return uuid; 20 | } 21 | 22 | function createDiv(className, id) { 23 | const div = $('
') 24 | div.addClass(className); 25 | id && div.attr('id', id); 26 | return div; 27 | } 28 | 29 | function createFragment() { 30 | const fragment = document.createDocumentFragment(); 31 | return $(fragment); 32 | } 33 | 34 | function createWxView() { 35 | return $(''); 36 | } -------------------------------------------------------------------------------- /WebPageNotes/codeSign/js/src/units/tools.js: -------------------------------------------------------------------------------- 1 | function formatArrayToTree(data, idKey = 'domId', parentKey = 'parentId') { 2 | const result = [] 3 | if(!Array.isArray(data)) { 4 | return result 5 | } 6 | data.forEach(item => { 7 | delete item.children; 8 | }); 9 | const map = {}; 10 | data.forEach(item => { 11 | map[item[idKey]] = item; 12 | }); 13 | data.forEach(item => { 14 | const parent = map[item[parentKey]]; 15 | if(parent) { 16 | (parent.children || (parent.children = [])).push(item); 17 | } else { 18 | result.push(item); 19 | } 20 | }); 21 | return result; 22 | } 23 | /** 24 | * javascript处理HTML的Decode(解码) 25 | * @param {*} str 26 | * @returns 27 | */ 28 | function htmlDecodeByRegExp (str){ 29 | var s = ""; 30 | if(!str || str.length == 0) return ""; 31 | s = str.replace(/&/g,"&"); 32 | s = s.replace(/</g,"<"); 33 | s = s.replace(/>/g,">"); 34 | s = s.replace(/ /g," "); 35 | s = s.replace(/'/g,"\'"); 36 | s = s.replace(/"/g,"\""); 37 | return s; 38 | } 39 | -------------------------------------------------------------------------------- /WebPageNotes/codeSign/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Popup 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Web_UI/mobile_table/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@wtechtec/mobile-table", 3 | "version": "0.0.21", 4 | "description": "移动端表格组件", 5 | "publishConfig": { 6 | "access": "public" 7 | }, 8 | "main": "dist/index.js", 9 | "module": "dist/index.esm.js", 10 | "unpkg": "./dist/index.umd.js", 11 | "types": "dist/index.d.ts", 12 | "scripts": { 13 | "build": "rollup -c", 14 | "prepublishOnly": "npm run build" 15 | }, 16 | "exports": { 17 | ".": { 18 | "import": "./dist/index.esm.js", 19 | "require": "./dist/index.js", 20 | "types": "./dist/index.d.ts" 21 | }, 22 | "./dist/index.css": "./dist/index.css" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "https://github.com/WtecHtec/WorkNotes/tree/master/Web_UI/mobile_table" 27 | }, 28 | "files": [ 29 | "dist" 30 | ], 31 | "keywords": [ 32 | "mobile", 33 | "table", 34 | "react" 35 | ], 36 | "author": "wtechtec", 37 | "license": "MIT", 38 | "peerDependencies": { 39 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0", 40 | "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", 41 | "@nutui/nutui-react": "^3.0.13" 42 | }, 43 | "devDependencies": { 44 | "@nutui/nutui-react": "^3.0.13", 45 | "@rollup/plugin-commonjs": "^21.0.0", 46 | "@rollup/plugin-node-resolve": "^13.0.0", 47 | "@rollup/plugin-typescript": "^8.3.0", 48 | "@types/react": "^19.1.6", 49 | "rollup": "^2.60.0", 50 | "rollup-plugin-postcss": "^4.0.2", 51 | "tslib": "^2.3.0", 52 | "typescript": "^4.5.0", 53 | "react": "^18.3.1", 54 | "react-dom": "^18.3.1", 55 | "classnames": "^2.5.1" 56 | } 57 | } -------------------------------------------------------------------------------- /Web_UI/mobile_table/rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from '@rollup/plugin-typescript'; 2 | import commonjs from '@rollup/plugin-commonjs'; 3 | import resolve from '@rollup/plugin-node-resolve'; 4 | import postcss from 'rollup-plugin-postcss'; 5 | import pkg from './package.json'; 6 | 7 | export default { 8 | input: 'src/index.ts', 9 | output: [ 10 | { 11 | file: pkg.main, 12 | format: 'cjs', 13 | sourcemap: true, 14 | exports: 'named', 15 | name: 'MobileTable' 16 | }, 17 | { 18 | file: pkg.module, 19 | format: 'esm', 20 | sourcemap: true, 21 | exports: 'named' 22 | }, 23 | { 24 | file: pkg.unpkg, 25 | format: 'umd', 26 | name: 'MobileTable' 27 | } 28 | ], 29 | external: (id) => { 30 | // 更严格的外部依赖检查 31 | return ['react', 'react-dom', '@nutui/nutui-react', '@nutui/icons-react', 'classnames'].includes(id) || 32 | id.startsWith('react/') || 33 | id.startsWith('react-dom/') || 34 | id.startsWith('@nutui/'); 35 | }, 36 | plugins: [ 37 | resolve({ 38 | extensions: ['.ts', '.tsx', '.js', '.jsx'], 39 | preferBuiltins: false, 40 | dedupe: ['react', 'react-dom'], 41 | // 防止解析 peer dependencies 42 | skip: ['react', 'react-dom', '@nutui/nutui-react', '@nutui/icons-react'] 43 | }), 44 | commonjs({ 45 | include: /node_modules/, 46 | exclude: ['react', 'react-dom', '@nutui/nutui-react', '@nutui/icons-react'], 47 | requireReturnsDefault: 'auto', 48 | transformMixedEsModules: true 49 | }), 50 | postcss({ 51 | inject: false, 52 | extract: 'index.css', // 提取到独立的CSS文件 53 | modules: false 54 | }), 55 | typescript({ 56 | tsconfig: './tsconfig.json', 57 | declaration: true, 58 | declarationDir: 'dist', 59 | rootDir: 'src' 60 | }) 61 | ] 62 | }; -------------------------------------------------------------------------------- /Web_UI/mobile_table/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationDir": "dist", 8 | "jsx": "react", 9 | "strict": true, 10 | "moduleResolution": "node", 11 | "esModuleInterop": true, 12 | "skipLibCheck": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "outDir": "dist", 15 | "rootDir": "src" 16 | }, 17 | "include": ["src"], 18 | "exclude": ["node_modules", "dist"] 19 | } -------------------------------------------------------------------------------- /Wx-Canvas-Dynamic/index/index.js: -------------------------------------------------------------------------------- 1 | // index.js 2 | // 获取应用实例 3 | const app = getApp() 4 | import { ThumbsUpAni } from '../../utils/ThumbsUpAni' 5 | Page({ 6 | data: { 7 | 8 | }, 9 | // 事件处理函数 10 | bindViewTap() { 11 | this.likeUpAni.start() 12 | }, 13 | onLoad() { 14 | 15 | }, 16 | onReady(){ 17 | const query = wx.createSelectorQuery() 18 | query.select('#likeCanvas') 19 | .fields({ node: true, size: true }) 20 | .exec((res) => { 21 | const canvas = res[0].node 22 | const ctx = canvas.getContext('2d') 23 | this.likeUpAni = new ThumbsUpAni(canvas, ctx) 24 | }) 25 | }, 26 | 27 | }) 28 | -------------------------------------------------------------------------------- /Wx-Canvas-Dynamic/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /Wx-Canvas-Dynamic/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Wx-Canvas-Dynamic/index/index.wxss: -------------------------------------------------------------------------------- 1 | .container { 2 | height: 100vh; 3 | position: relative; 4 | } -------------------------------------------------------------------------------- /Wx-QianMing/draw.js: -------------------------------------------------------------------------------- 1 | const Draw = function (canvasID,canvas, width, height, pixelRatio, config = {}) { 2 | 3 | if (!(this instanceof Draw)) { 4 | return new Draw(canvas, config); 5 | } 6 | if (!canvas) { 7 | return; 8 | } 9 | 10 | console.log('canvas', canvas) 11 | 12 | this.canvas = canvas; 13 | this.context = canvas.getContext('2d'); 14 | this.width = width; 15 | this.height = height; 16 | const context = this.context; 17 | // 根据设备像素比优化canvas绘图 18 | const devicePixelRatio = pixelRatio; 19 | 20 | if (devicePixelRatio) { 21 | canvas.height = height * devicePixelRatio; 22 | canvas.width = width * devicePixelRatio; 23 | context.scale(devicePixelRatio, devicePixelRatio); 24 | } else { 25 | canvas.width = width; 26 | canvas.height = height; 27 | } 28 | context.fillStyle = '#fff' 29 | context.fillRect(0, 0, this.width, this.height ) 30 | 31 | 32 | context.lineWidth = 6; 33 | context.strokeStyle = 'black'; 34 | 35 | 36 | const { _left: left = 0, _top: top = 0 } = canvas; 37 | const point = {}; 38 | 39 | let pressed = false; 40 | 41 | const paint = (signal) => { 42 | switch (signal) { 43 | case 1: 44 | context.beginPath(); 45 | context.moveTo(point.x, point.y); 46 | case 2: 47 | context.lineTo(point.x, point.y); 48 | context.stroke(); 49 | break; 50 | default: 51 | } 52 | }; 53 | 54 | const create = signal => (e) => { 55 | if (signal === 1) { 56 | pressed = true; 57 | } 58 | if (signal === 1 || pressed) { 59 | point.x = e.x - left; 60 | point.y = e.y - top; 61 | paint(signal); 62 | } 63 | }; 64 | this.start = create(1); 65 | this.move = create(2); 66 | this.clear = ()=>{ 67 | context.fillStyle = '#fff' 68 | context.fillRect(0, 0, this.width, this.height ) 69 | } 70 | } 71 | export { 72 | Draw 73 | } -------------------------------------------------------------------------------- /Wx-QianMing/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {}, 3 | "disableScroll": true 4 | } -------------------------------------------------------------------------------- /Wx-QianMing/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Wx-QianMing/index.wxss: -------------------------------------------------------------------------------- 1 | /* pages/qianming/index.wxss */ 2 | .qianm-main { 3 | overflow: hidden; 4 | width: 100%; 5 | height: 100vh; 6 | } -------------------------------------------------------------------------------- /Wx-QianMing/wordUtils.js: -------------------------------------------------------------------------------- 1 | const getToken = function() { 2 | let client_id = '' 3 | let client_secret = '' 4 | let url =`https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${client_id}&client_secret=${client_secret}` 5 | wx.request({ 6 | url: url, //仅为示例,并非真实的接口地址 7 | method: 'POST', 8 | header: { 9 | 'content-type': 'application/json' // 默认值 10 | }, 11 | success (res) { 12 | console.log(res.data) 13 | } 14 | }) 15 | } 16 | 17 | const AT = '' 18 | 19 | const getWord = function(AT, images) { 20 | let url = `https://aip.baidubce.com/rest/2.0/ocr/v1/handwriting?access_token=${AT}` 21 | return new Promise((resolve, reject)=>{ 22 | wx.request({ 23 | url: url, //仅为示例,并非真实的接口地址 24 | method: 'POST', 25 | header: { 26 | 'Content-Type': 'application/x-www-form-urlencoded' // 默认值 27 | }, 28 | data: { 29 | image: images 30 | }, 31 | success (res) { 32 | resolve(res) 33 | } 34 | }) 35 | 36 | }) 37 | } 38 | export { 39 | getToken, 40 | AT, 41 | getWord, 42 | } 43 | -------------------------------------------------------------------------------- /Wx-美团日期/conmon.js: -------------------------------------------------------------------------------- 1 | export function dateFromat(date){ 2 | if (date instanceof Date) { 3 | let y = date.getFullYear(); 4 | let m = date.getMonth() + 1; 5 | m = m > 9 ? m : '0' + m; 6 | let d = date.getDate(); 7 | return y + '/' + m + '/' + d; 8 | } else { 9 | throw new Error('date 不是 Date 类型') 10 | } 11 | } -------------------------------------------------------------------------------- /Wx-美团日期/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /Wx-美团日期/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{item}} 4 | 5 | 8 | 9 | 10 | {{ item.year + '-' + item.month}} 11 | 12 | 13 | 14 | {{ itemDay.hidden ? '': itemDay.date }} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 完成 23 | 24 | 25 | -------------------------------------------------------------------------------- /Wx-美团日期/index.wxss: -------------------------------------------------------------------------------- 1 | .date-context { 2 | width: 100%; 3 | height: 100vh; 4 | position: relative; 5 | overflow: hidden; 6 | } 7 | .week-main { 8 | margin-bottom: 24rpx; 9 | display: flex; 10 | height: 46rpx; 11 | position: relative; 12 | } 13 | .week-item { 14 | width: calc(100vw / 7); 15 | line-height: 46rpx; 16 | text-align: center; 17 | font-size: 24rpx; 18 | color: #999; 19 | } 20 | 21 | .date-list { 22 | margin-bottom: 16rpx; 23 | } 24 | .date-main { 25 | display: flex; 26 | flex-wrap: wrap; 27 | 28 | } 29 | 30 | .date-title { 31 | padding: 0 30rpx; 32 | font-size: 28rpx; 33 | color: #666; 34 | margin-bottom: 12rpx; 35 | } 36 | .date-item { 37 | width: calc(100vw / 7); 38 | height: 128rpx; 39 | display: flex; 40 | justify-content: center; 41 | align-items: center; 42 | } 43 | .-disabled{ 44 | color: #999; 45 | } 46 | .-active { 47 | background: #265cf0; 48 | font-weight: 700; 49 | color: #fff; 50 | } 51 | 52 | .-pass { 53 | background: #e5ebfd; 54 | } 55 | .footer { 56 | position: absolute; 57 | width: 100%; 58 | bottom: 0; 59 | padding: 24rpx; 60 | box-sizing: border-box; 61 | } 62 | .btn-normal { 63 | position: relative; 64 | display: inline-block; 65 | width: 100%; 66 | height: 90rpx; 67 | line-height: 90rpx; 68 | background: #265CF0; 69 | border-radius: 8rpx; 70 | font-size: 32rpx; 71 | color: #FFFFFF; 72 | text-align: center; 73 | padding: 0rpx; 74 | } 75 | .-hover-btn { 76 | background: rgba(38,92,240, 0.8); 77 | } 78 | .-hidden-btn { 79 | transform: translateY(70Px); 80 | transition: all ease-in 0.2s; 81 | } 82 | .-show-btn { 83 | transform: translateY(0Px); 84 | transition: all ease-in 0.2s; 85 | } -------------------------------------------------------------------------------- /bmgame/demo1/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /bmgame/demo1/img/firetorch_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/bmgame/demo1/img/firetorch_1.jpg -------------------------------------------------------------------------------- /bmgame/demo1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - node particles 5 | 6 | 7 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /bmgame/server.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/bmgame/server.tar -------------------------------------------------------------------------------- /bmgame/server/game3D/backgammon.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 五子棋 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 29 | 30 | 31 | 32 |
33 |
状态:
34 |
玩家:
35 |
邀请好友一起游戏:
36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /bmgame/server/game3D/js/backgammon/index.js: -------------------------------------------------------------------------------- 1 | function getQueryString(name) { 2 | var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'); //设置正则匹配规范 3 | var r = window.location.search.substr(1).match(reg); // 获取“?”后的字符串并正则匹配 4 | if (r != null) { 5 | return decodeURIComponent(r[2]); // 解码参数部分 6 | } 7 | return null; 8 | } 9 | 10 | window.onload = ()=> { 11 | const roomId = getQueryString('room') 12 | const socket = io(); 13 | new BMGame(socket, roomId); 14 | } -------------------------------------------------------------------------------- /bmgame/server/game3D/js/backgammon/player.js: -------------------------------------------------------------------------------- 1 | class Player { 2 | /** 3 | * 4 | * @param {*} name 玩家名称 5 | * @param {*} pieceType 棋子颜色 6 | */ 7 | constructor(name, pieceType) { 8 | this.name = name 9 | /** 10 | * 棋子颜色 11 | * w: 白色 12 | * b: 黑色 13 | */ 14 | this.pieceType = pieceType 15 | } 16 | } -------------------------------------------------------------------------------- /bmgame/server/game3D/js/index.js: -------------------------------------------------------------------------------- 1 | //页面加载完成 2 | window.onload = function(){ 3 | createWorld(); 4 | } 5 | 6 | function createWorld() { 7 | initRender("game");//创建渲染器 8 | initCamera();//创建相机 9 | initLight();//创建光源 10 | initObject();//创建物体 11 | initScene();//创建场景 12 | render();//渲染 13 | } 14 | 15 | var renderer;//渲染器 16 | var width; 17 | var height; 18 | /** 19 | * 创建渲染器 20 | * @param {*} selector 元素id 21 | */ 22 | function initRender(selector){ 23 | width = window.innerWidth; 24 | height = window.innerHeight; 25 | renderer = new THREE.WebGLRenderer({ 26 | antialias : true//抗锯齿开启 27 | }); 28 | renderer.setSize(width, height);//设置渲染器宽度和高度 29 | renderer.setClearColor('#ffffff', 1.0);//设置背景颜色 30 | renderer.setPixelRatio(window.devicePixelRatio);//设置设备像素比 31 | document.getElementById(selector).appendChild(renderer.domElement);//把渲染器放置到页面中 32 | } 33 | 34 | var camera; 35 | var origPoint = new THREE.Vector3(0, 0, 0);//原点 36 | /** 37 | * 创建摄像机 38 | */ 39 | function initCamera(){ 40 | camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000); 41 | camera.position.set(200, 400, 600);//设置相机位置 42 | camera.up.set(0, 1, 0);//设置相机正方向 43 | camera.lookAt(origPoint);//设置相机视点 44 | } 45 | 46 | var pointLight; 47 | var ambientLight; 48 | function initLight() { 49 | //点光源 50 | pointLight = new THREE.PointLight( 0xffffff, 1, 2000 ); 51 | pointLight.position.set(70, 112, 98); 52 | //环境光 53 | ambientLight = new THREE.AmbientLight( 0x333333 ); 54 | } 55 | 56 | var cube; 57 | function initObject(){ 58 | var geometry = new THREE.BoxGeometry( 100, 100, 100); 59 | var material = new THREE.MeshLambertMaterial( {color: 0xff0000} ); 60 | cube = new THREE.Mesh( geometry, material ); 61 | cube.position.set(0,0,0); 62 | } 63 | 64 | var scene; 65 | function initScene(){ 66 | scene = new THREE.Scene(); 67 | // scene.add(pointLight); 68 | // scene.add(ambientLight); 69 | // scene.add(cube) 70 | scene.background = new THREE.Color('#478967') 71 | return scene 72 | } 73 | 74 | function render(){ 75 | renderer.clear(); 76 | renderer.render(scene, camera); 77 | requestAnimationFrame(render); 78 | } -------------------------------------------------------------------------------- /bmgame/server/game3D/js/rubiks/components/camera.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 创建摄像机 3 | * @returns 摄像机实例 4 | */ 5 | function createCamera() { 6 | const camera = new THREE.PerspectiveCamera( 7 | 45, 8 | 1, 9 | 0.1, 10 | 100 11 | ); 12 | 13 | camera.position.set(0, 0, 15); 14 | 15 | return camera; 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /bmgame/server/game3D/js/rubiks/components/renderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 创建一个three渲染器 3 | * @returns 渲染器实例 4 | */ 5 | const createRenderer = () => { 6 | const renderer = new THREE.WebGLRenderer({antialias: true}); //抗锯齿开启 7 | return renderer; 8 | }; -------------------------------------------------------------------------------- /bmgame/server/game3D/js/rubiks/components/scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 创建场景 3 | * @param {*} bgColor 场景背景颜色 4 | * @returns 场景实例 5 | */ 6 | const createScene = (bgColor) => { 7 | const scene = new THREE.Scene(); 8 | 9 | scene.background = new THREE.Color(bgColor); 10 | 11 | return scene; 12 | }; 13 | -------------------------------------------------------------------------------- /bmgame/server/game3D/js/rubiks/core/MouseControl.js: -------------------------------------------------------------------------------- 1 | class MouseControl extends Control { 2 | constructor(camera, scene, renderer, cube) { 3 | super(camera, scene, renderer, cube); 4 | 5 | this.mousedownHandle = this.mousedownHandle.bind(this); 6 | this.mouseupHandle = this.mouseupHandle.bind(this); 7 | this.mousemoveHandle = this.mousemoveHandle.bind(this); 8 | this.mouseoutHandle = this.mouseoutHandle.bind(this); 9 | 10 | this.init(); 11 | } 12 | mousedownHandle(event) { 13 | event.preventDefault(); 14 | this.operateStart(event.offsetX, event.offsetY); 15 | } 16 | 17 | mouseupHandle(event) { 18 | event.preventDefault(); 19 | this.operateEnd(); 20 | } 21 | 22 | mouseoutHandle(event) { 23 | event.preventDefault(); 24 | this.operateEnd(); 25 | } 26 | 27 | mousemoveHandle(event) { 28 | event.preventDefault(); 29 | 30 | this.operateDrag(event.offsetX, event.offsetY, event.movementX, event.movementY); 31 | } 32 | 33 | init() { 34 | this.domElement.addEventListener("mousedown", this.mousedownHandle); 35 | this.domElement.addEventListener("mouseup", this.mouseupHandle); 36 | this.domElement.addEventListener("mousemove", this.mousemoveHandle); 37 | this.domElement.addEventListener("mouseout", this.mouseoutHandle); 38 | } 39 | dispose() { 40 | this.domElement.removeEventListener("mousedown", this.mousedownHandle); 41 | this.domElement.removeEventListener("mouseup", this.mouseupHandle); 42 | this.domElement.removeEventListener("mousemove", this.mousemoveHandle); 43 | this.domElement.removeEventListener("mouseout", this.mouseoutHandle); 44 | } 45 | } -------------------------------------------------------------------------------- /bmgame/server/game3D/js/rubiks/index.js: -------------------------------------------------------------------------------- 1 | //页面加载完成 2 | window.onload = function(){ 3 | createWorld(); 4 | } 5 | var camera ; 6 | var scene; 7 | var renderer; 8 | var cube; 9 | function createWorld() { 10 | const container = document.getElementById('game') 11 | camera = createCamera(); 12 | scene = createScene('#478967'); 13 | renderer = createRenderer() 14 | container.appendChild(renderer.domElement);//把渲染器放置到页面中 15 | setSize(container, camera, renderer) 16 | setOrder() 17 | // new MouseControl(camera, scene, renderer, cube) 18 | // new THREE.OrbitControls(camera, renderer.domElement ) 19 | startAnimation() 20 | } 21 | /** 22 | * 渲染器渲染场景 23 | */ 24 | function render() { 25 | renderer.render(scene, camera); 26 | } 27 | /** 28 | * 设置场景大小 29 | * @param {*} container 元素 30 | * @param {*} camera 摄像机 31 | * @param {*} renderer 渲染器 32 | */ 33 | function setSize(container, camera, renderer) { 34 | // 设置相机的纵横比 35 | camera.aspect = container.clientWidth / container.clientHeight; 36 | camera.updateProjectionMatrix(); 37 | 38 | // 设置渲染器宽度和高度 39 | renderer.setSize(container.clientWidth, container.clientHeight); 40 | 41 | // 设置设备像素比 42 | renderer.setPixelRatio(window.devicePixelRatio); 43 | }; 44 | 45 | /** 46 | * 启动帧刷新 47 | */ 48 | function startAnimation() { 49 | const animation = (time) => { 50 | // time /= 1000; // convert to seconds 51 | // if (this.cube) { 52 | // if (time < 2) { 53 | // this.cube.position.z = (-1 + time / 2) * 100; 54 | // } else { 55 | // this.cube.position.z = 0; 56 | // } 57 | // const dis = time; 58 | // this.cube.position.y = Math.sin(dis) * 0.3; 59 | // } 60 | render(); 61 | requestAnimationFrame(animation); 62 | }; 63 | 64 | requestAnimationFrame(animation); 65 | } 66 | 67 | /** 68 | * 设置几阶魔方 69 | */ 70 | function setOrder() { 71 | cube = new Cube(3); 72 | scene.add(cube); 73 | render(); 74 | } -------------------------------------------------------------------------------- /bmgame/server/game3D/js/rubiks/util/math.js: -------------------------------------------------------------------------------- 1 | // import {Vector2, Vector3} from "three"; 2 | 3 | /** 4 | * get the angle between two Vector2 5 | * @returns angles in radian 6 | */ 7 | function getAngleBetweenTwoVector2 (vec1, vec2) { 8 | const dotValue = vec1.clone().dot(vec2); 9 | const angle = Math.acos(dotValue / (vec1.length() * vec2.length())); 10 | return angle; 11 | }; 12 | 13 | function equalDirection (vec1, vec2, precision = 0.1) { 14 | const angle = vec1.angleTo(vec2); 15 | return Math.abs(angle) < precision; 16 | }; 17 | 18 | 19 | function setFinish (finish) { 20 | const finishEle = document.getElementById("finish"); 21 | // if (finishEle) { 22 | // finishEle.innerText = finish ? "👏 恭喜!" : "🤔 加油"; 23 | // } 24 | }; -------------------------------------------------------------------------------- /bmgame/server/game3D/js/rubiks/util/transform.js: -------------------------------------------------------------------------------- 1 | 2 | function rotateAroundWorldAxis(object, axis, radians) { 3 | const mat = new THREE.Matrix4(); 4 | mat.makeRotationAxis(axis.normalize(), radians); 5 | 6 | mat.multiply(object.matrix); 7 | 8 | object.matrix = mat; 9 | 10 | object.rotation.setFromRotationMatrix(object.matrix); 11 | }; 12 | 13 | function ndcToScreen(ndc, winW, winH ){ 14 | const halfW = winW * 0.5; 15 | const halfH = winH * 0.5; 16 | 17 | const x = (ndc.x * halfW) + halfW; 18 | const y = halfH - (ndc.y * halfH); 19 | 20 | return {x, y}; 21 | }; 22 | -------------------------------------------------------------------------------- /bmgame/server/game3D/readme.md: -------------------------------------------------------------------------------- 1 | # THREE 五大要素 2 | 渲染器、摄像机、场景 3 | -------------------------------------------------------------------------------- /bmgame/server/game3D/rubiks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 魔方游戏 online | Rubik cube 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /bmgame/server/game3D/textures/square-outline-textured.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/bmgame/server/game3D/textures/square-outline-textured.png -------------------------------------------------------------------------------- /bmgame/server/game3D/textures/square-outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/bmgame/server/game3D/textures/square-outline.png -------------------------------------------------------------------------------- /bmgame/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "express": "^4.18.2", 14 | "socket.io": "^4.5.4", 15 | "uuid": "^9.0.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /canvan-chart/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /canvan-chart/js/drawutil.js: -------------------------------------------------------------------------------- 1 | class DrawUtil{ 2 | constructor(ctx) { 3 | try { 4 | if (!(ctx instanceof CanvasRenderingContext2D)) throw '画布实例对象错误!' 5 | this.ctx = ctx 6 | } catch (e) { 7 | console.error(e) 8 | } 9 | } 10 | drawLineVertical(x1,x2, top=0, left=0) { 11 | let ctx = this.ctx 12 | ctx.beginPath(); 13 | ctx.moveTo(x1 + left, top); 14 | ctx.lineTo(x2 + left, top); 15 | ctx.closePath(); 16 | ctx.stroke(); 17 | } 18 | 19 | drawLineHorizontal(y1,y2, top=0, left=0) { 20 | let ctx = this.ctx 21 | ctx.beginPath(); 22 | ctx.moveTo(left, y1 + top); 23 | ctx.lineTo(left, y2 + top); 24 | ctx.closePath(); 25 | ctx.stroke(); 26 | } 27 | } -------------------------------------------------------------------------------- /canvan-chart/js/scalelinear.js: -------------------------------------------------------------------------------- 1 | class MyScaleLinear { 2 | constructor() { 3 | this.domainVal = [] 4 | this.rangeVal = [] 5 | } 6 | domain(arr) { 7 | try { 8 | if (!Array.isArray(arr)) throw 'domain 参数不是一个数组!'; 9 | if (arr.length !== 2) throw 'domain 数组长度不为2'; 10 | this.domainVal = [...arr]; 11 | } 12 | catch (e) { 13 | console.error(e) 14 | } 15 | return this; 16 | } 17 | range(arr) { 18 | try { 19 | if (!Array.isArray(arr)) throw 'domain 参数不是一个数组!'; 20 | if (arr.length !== 2) throw 'domain 数组长度不为2'; 21 | this.rangeVal = [...arr]; 22 | } 23 | catch (e) { 24 | console.error(e) 25 | } 26 | return this.findRange.bind(this); 27 | } 28 | 29 | findRange(val){ 30 | let result = (val - this.domainVal[0]) / (this.domainVal[1] - this.domainVal[0]) * (this.rangeVal[1] - this.rangeVal[0]) + this.rangeVal[0]; 31 | return result 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /canvan-chart/js/scaleordinal.js: -------------------------------------------------------------------------------- 1 | class MyScaleOrdinal { 2 | constructor() { 3 | this.domainVal = [] 4 | this.rangeVal = [] 5 | } 6 | domain(arr) { 7 | try { 8 | if (!Array.isArray(arr)) throw 'domain 参数不是一个数组。' 9 | this.domainVal = [...arr] 10 | } catch (e) { 11 | console.error(e) 12 | } 13 | return this 14 | } 15 | range(arr) { 16 | try { 17 | if (!Array.isArray(arr)) throw 'range 参数不是一个数组。' 18 | this.rangeVal = [...arr] 19 | } catch (e) { 20 | console.error(e) 21 | } 22 | return this.findRange.bind(this); 23 | } 24 | findRange(val){ 25 | let index = this.domainVal.findIndex((item) => item === val); 26 | let rlen = this.rangeVal.length 27 | if (rlen > index) return this.rangeVal[index] 28 | return this.rangeVal[index % rlen]; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /canvan-chart/js/scalepie.js: -------------------------------------------------------------------------------- 1 | class ScalePie{ 2 | constructor() { 3 | this.arcData = [] 4 | this.hasValueFunc = false 5 | this.valueFunc = null 6 | } 7 | value(fn) { 8 | this.hasValueFunc = true; 9 | this.valueFunc = fn 10 | return this 11 | } 12 | getArcs(arr) { 13 | try { 14 | if (!Array.isArray(arr)) throw 'getArcs 参数为非数组' 15 | this.arcData = [...arr] 16 | this.arcData.sort((a, b) =>{ 17 | if (this.hasValueFunc) return this.valueFunc(b) - this.valueFunc(a) 18 | return b - a 19 | }) 20 | let totals = this.arcData.reduce((total, num) => { 21 | if ( this.hasValueFunc) return total + this.valueFunc(num) 22 | return total + num 23 | },0) 24 | let result = [] 25 | let resObj = {} 26 | let resValue = 0 27 | let lastAngle = 0 28 | let currentAngle = 0 29 | this.arcData.forEach((num)=>{ 30 | resValue = num 31 | if ( this.hasValueFunc) resValue = this.valueFunc(num) 32 | currentAngle = lastAngle + resValue / totals * Math.PI * 2 33 | resObj = { 34 | data: num, 35 | value: resValue, 36 | startAngle: lastAngle, 37 | endAngle: currentAngle 38 | } 39 | result.push(resObj) 40 | lastAngle = currentAngle 41 | }) 42 | return result 43 | } catch (e) { 44 | console.error(e) 45 | } 46 | return [] 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /echartBmap/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.detectIndentation": false, 3 | "editor.tabSize": 4, 4 | "editor.formatOnPaste": true, 5 | "editor.formatOnSave": true 6 | } -------------------------------------------------------------------------------- /echartBmap/README.md: -------------------------------------------------------------------------------- 1 | 2 | https://juejin.im/post/6891203499414323208/ -------------------------------------------------------------------------------- /exportExecl/Export2Zip.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('script-loader!file-saver'); 3 | import JSZip from 'jszip' 4 | 5 | export function export_txt_to_zip(th, jsonData, txtName, zipName) { 6 | const zip = new JSZip() 7 | const txt_name = txtName || 'file' 8 | const zip_name = zipName || 'file' 9 | const data = jsonData 10 | let txtData = `${th}\r\n` 11 | data.forEach((row) => { 12 | let tempStr = '' 13 | tempStr = row.toString() 14 | txtData += `${tempStr}\r\n` 15 | }) 16 | zip.file(`${txt_name}.txt`, txtData) 17 | zip.generateAsync({type:"blob"}).then((blob) => { 18 | saveAs(blob, `${zip_name}.zip`) 19 | }, (err) => { 20 | alert('导出失败') 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /go_makemask/font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/go_makemask/font.ttf -------------------------------------------------------------------------------- /go_makemask/go.mod: -------------------------------------------------------------------------------- 1 | module mask 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/fogleman/gg v1.3.0 // indirect 7 | github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect 8 | golang.org/x/image v0.1.0 // indirect 9 | ) 10 | -------------------------------------------------------------------------------- /go_makemask/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "mask/watermarker" 6 | ) 7 | 8 | func main() { 9 | fmt.Print("开始") 10 | imgPtah := "./test.jpg" 11 | desc := "测试" 12 | outPath := "./test-water.jpg" 13 | watermarker.MakeWaterMarker(imgPtah, desc, outPath) 14 | } 15 | -------------------------------------------------------------------------------- /go_makemask/test-water.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/go_makemask/test-water.jpg -------------------------------------------------------------------------------- /go_makemask/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/go_makemask/test.jpg -------------------------------------------------------------------------------- /go_makemask/watermarker/water_marker.go: -------------------------------------------------------------------------------- 1 | package watermarker 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/fogleman/gg" 7 | ) 8 | 9 | func MakeWaterMarker(imgPath string, waterDesc string, outPath string) bool { 10 | im, err := gg.LoadImage(imgPath) 11 | if err != nil { 12 | return false 13 | } 14 | w := im.Bounds().Size().X 15 | h := im.Bounds().Size().Y 16 | fmt.Print(w, h) 17 | dc := gg.NewContext(w, h) 18 | rd := w / 375 19 | if rd == 0 { 20 | rd = 1 21 | } 22 | if err := dc.LoadFontFace("./font.ttf", float64(rd*24)); err != nil { 23 | fmt.Print(err) 24 | return false 25 | } 26 | dc.DrawImage(im, 0, 0) 27 | sw, sh := dc.MeasureString(waterDesc) 28 | dc.SetRGBA(99, 99, 99, 0.6) 29 | for j := 0; j < h; j += (int(sh + float64(30*rd))) { 30 | for i := 0; i < w; i += (int(sw + float64(24*rd))) { 31 | dc.Push() 32 | dc.DrawString(waterDesc, float64(i), float64(j)) 33 | dc.Pop() 34 | } 35 | } 36 | dc.SavePNG(outPath) 37 | return true 38 | } 39 | -------------------------------------------------------------------------------- /golang/imooc-maze/maze.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func readMaze(pathFile string) ([][]int, bool) { 9 | file, err := os.Open(pathFile) 10 | if err != nil { 11 | return nil, false 12 | } 13 | defer file.Close() 14 | var row, col int 15 | fmt.Fscanf(file, "%d %d", &row, &col) 16 | mazes := make([][]int, row) 17 | for i := range mazes { 18 | mazes[i] = make([]int, col) 19 | for j := range mazes[i] { 20 | fmt.Fscanf(file, "%d", &mazes[i][j]) 21 | } 22 | } 23 | return mazes, true 24 | } 25 | 26 | type point struct { 27 | i, j int 28 | } 29 | 30 | var dirs = [4]point{ 31 | {-1, 0}, 32 | {0, -1}, 33 | {1, 0}, 34 | {0, 1}, 35 | } 36 | 37 | func (p *point) add(r point) point { 38 | return point{p.i + r.i, p.j + r.j} 39 | } 40 | 41 | func (p *point) at(gird [][]int) (int, bool) { 42 | if p.i < 0 || p.i >= len(gird) { 43 | return 0, false 44 | } 45 | if p.j < 0 || p.j >= len(gird[p.i]) { 46 | return 0, false 47 | } 48 | return gird[p.i][p.j], true 49 | } 50 | func walk(maze [][]int, start, end point) [][]int { 51 | steps := make([][]int, len(maze)) 52 | for i := range maze { 53 | steps[i] = make([]int, len(maze[i])) 54 | } 55 | Q := []point{start} 56 | for len(Q) > 0 { 57 | cur := Q[0] 58 | Q = Q[1:] 59 | if cur == end { 60 | break 61 | } 62 | for _, dir := range dirs { 63 | next := cur.add(dir) 64 | value, ok := next.at(maze) 65 | if !ok || value == 1 { 66 | continue 67 | } 68 | nvalue, nok := next.at(steps) 69 | if !nok || nvalue != 0 { 70 | continue 71 | } 72 | if next == start { 73 | continue 74 | } 75 | curStep, _ := cur.at(steps) 76 | steps[next.i][next.j] = curStep + 1 77 | Q = append(Q, next) 78 | } 79 | } 80 | return steps 81 | } 82 | func stepsPlint(step [][]int) { 83 | for _, value := range step { 84 | fmt.Printf("%3d\n", value) 85 | } 86 | } 87 | func main() { 88 | // 读取文件 89 | mazes, _ := readMaze("maze/maze.in") 90 | // 计算步数 91 | steps := walk(mazes, point{0, 0}, point{len(mazes) - 1, len(mazes[0]) - 1}) 92 | // 打印 93 | stepsPlint(steps) 94 | } 95 | -------------------------------------------------------------------------------- /golang/imooc-maze/maze.in: -------------------------------------------------------------------------------- 1 | 6 5 2 | 0 1 0 0 0 3 | 0 0 0 1 0 4 | 0 1 0 1 0 5 | 1 1 1 0 0 6 | 0 1 0 0 1 7 | 0 1 0 0 0 -------------------------------------------------------------------------------- /golang/share_car/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Eslint config file 3 | * Documentation: https://eslint.org/docs/user-guide/configuring/ 4 | * Install the Eslint extension before using this feature. 5 | */ 6 | module.exports = { 7 | env: { 8 | es6: true, 9 | browser: true, 10 | node: true, 11 | }, 12 | ecmaFeatures: { 13 | modules: true, 14 | }, 15 | parserOptions: { 16 | ecmaVersion: 2018, 17 | sourceType: 'module', 18 | }, 19 | globals: { 20 | wx: true, 21 | App: true, 22 | Page: true, 23 | getCurrentPages: true, 24 | getApp: true, 25 | Component: true, 26 | requirePlugin: true, 27 | requireMiniProgram: true, 28 | }, 29 | // extends: 'eslint:recommended', 30 | rules: {}, 31 | } 32 | -------------------------------------------------------------------------------- /golang/share_car/app.js: -------------------------------------------------------------------------------- 1 | // app.js 2 | App({ 3 | onLaunch (options) { 4 | // Do something initial when launch. 5 | }, 6 | }) 7 | -------------------------------------------------------------------------------- /golang/share_car/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/index/index", 4 | "pages/register/index", 5 | "pages/unlock/index", 6 | "pages/driving/index" 7 | ], 8 | "permission": { 9 | "scope.userLocation": { 10 | "desc": "你的位置信息将用于小程序位置接口的效果展示" 11 | } 12 | }, 13 | "window": { 14 | "backgroundTextStyle": "light", 15 | "navigationBarBackgroundColor": "#fff", 16 | "navigationBarTitleText": "Weixin", 17 | "navigationBarTextStyle": "black" 18 | }, 19 | "style": "v2", 20 | "sitemapLocation": "sitemap.json" 21 | } -------------------------------------------------------------------------------- /golang/share_car/app.wxss: -------------------------------------------------------------------------------- 1 | .wapp-image { 2 | width: 100%; 3 | height: 100%; 4 | } -------------------------------------------------------------------------------- /golang/share_car/assets/images/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/golang/share_car/assets/images/car.png -------------------------------------------------------------------------------- /golang/share_car/assets/images/maker-car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/golang/share_car/assets/images/maker-car.png -------------------------------------------------------------------------------- /golang/share_car/assets/images/person.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/golang/share_car/assets/images/person.png -------------------------------------------------------------------------------- /golang/share_car/assets/images/postion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/golang/share_car/assets/images/postion.png -------------------------------------------------------------------------------- /golang/share_car/components/word-cloud/README.md: -------------------------------------------------------------------------------- 1 | list 格式1: [ 显示内容, 内容大小,内容颜色] 2 | 3 | 4 | 5 | list: [ 6 | ['Google', 15, 'red'], 7 | ['JD', 12], 8 | ['GoogleA', 10], 9 | ['Alibaba', 7], 10 | ['Baidu', 6], 11 | ['NetEase', 4], 12 | ['Youku', 4], 13 | ['Meituan', 3], 14 | ['Douban', 3], 15 | ] 16 | 17 | 18 | list 格式2: 19 | 20 | list: [ 21 | { 22 | word: 'Google', 23 | weight: 15, 24 | color: 'red', 25 | }, 26 | { 27 | word: 'JD', 28 | weight: 12, 29 | }, 30 | { 31 | word: 'GoogleA', 32 | weight: 10, 33 | }, 34 | { 35 | word: 'Tencent', 36 | weight: 9, 37 | }, 38 | ], 39 | -------------------------------------------------------------------------------- /golang/share_car/components/word-cloud/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /golang/share_car/components/word-cloud/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ item.word }} 5 | 6 | 7 | -------------------------------------------------------------------------------- /golang/share_car/components/word-cloud/index.wxss: -------------------------------------------------------------------------------- 1 | /* components/word-cloud/index.wxss */ 2 | 3 | .wc-canvas { 4 | display: none; 5 | position: absolute; 6 | z-index: -1; 7 | } 8 | .wc-main { 9 | position: relative; 10 | } 11 | .wc-item { 12 | white-space: nowrap; 13 | position: absolute; 14 | display: block; 15 | transform-origin: 50% 40%; 16 | } 17 | -------------------------------------------------------------------------------- /golang/share_car/pages/driving/index.js: -------------------------------------------------------------------------------- 1 | // pages/driving/index.js 2 | const diff_free = 0.7 3 | function formatMoney(money) { 4 | return (money / 100).toFixed(2); 5 | } 6 | function padString(num) { 7 | return num < 10 ? `0${num}` : num; 8 | } 9 | function formatTime(sec) { 10 | const h = Math.floor(sec / 3600) 11 | sec = sec % 3600 12 | const m = Math.floor(sec / 60) 13 | sec = sec % 60 14 | const s = Math.floor(sec) 15 | return `${padString(h)}:${padString(m)}:${padString(s)}` 16 | } 17 | Page({ 18 | timer: null, 19 | /** 20 | * 页面的初始数据 21 | */ 22 | data: { 23 | latitude: 32.92, 24 | longitude: 116.46, 25 | scale: 18, 26 | showTime: "00:00:00", 27 | showMoney: "0.00", 28 | isEnd: false, 29 | }, 30 | 31 | /** 32 | * 生命周期函数--监听页面加载 33 | */ 34 | onLoad: function (options) { 35 | this.onPostion() 36 | this.onCountFree() 37 | }, 38 | onPostion() { 39 | wx.startLocationUpdate({ fail(err) {console.error(err)}}) 40 | wx.onLocationChange((res)=> { 41 | this.setData({ 42 | latitude: res.latitude, 43 | longitude: res.longitude, 44 | }) 45 | }) 46 | }, 47 | onHide() { 48 | this.timer && clearInterval(this.timer) 49 | }, 50 | onEndDire() { 51 | this.timer && clearInterval(this.timer) 52 | this.setData({ 53 | isEnd: true, 54 | }) 55 | }, 56 | onCountFree() { 57 | let sec = 0; 58 | let money = 0; 59 | this.timer = setInterval(()=> { 60 | sec = sec + 1; 61 | money = money + diff_free; 62 | this.setData({ 63 | showTime: formatTime(sec), 64 | showMoney: formatMoney(money), 65 | }) 66 | }, 1000) 67 | } 68 | }) -------------------------------------------------------------------------------- /golang/share_car/pages/driving/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "行程", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /golang/share_car/pages/driving/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{showTime}} 4 | 费用:{{showMoney}}元 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /golang/share_car/pages/driving/index.wxss: -------------------------------------------------------------------------------- 1 | .content { 2 | width: 100%; 3 | height: 100vh; 4 | display: flex; 5 | flex-direction: column-reverse; 6 | } 7 | .map { 8 | width: 100%; 9 | flex: 1; 10 | } 11 | .order-content { 12 | display: flex; 13 | flex-direction: column; 14 | align-items: center; 15 | padding: 32rpx 0; 16 | } 17 | .time { 18 | font-size: 36rpx; 19 | font-weight: bold; 20 | } 21 | .money { 22 | margin: 12rpx 0; 23 | } -------------------------------------------------------------------------------- /golang/share_car/pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "享车", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /golang/share_car/pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 扫码用车 9 | 10 | 11 | -------------------------------------------------------------------------------- /golang/share_car/pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | page { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | .map-content { 6 | width: 100%; 7 | height: 100%; 8 | position: relative; 9 | } 10 | 11 | .nav { 12 | display: flex; 13 | flex-direction: column; 14 | justify-content: space-between; 15 | width: 88rpx; 16 | height: 160rpx; 17 | padding-top: 16rpx; 18 | } 19 | 20 | .nav-img { 21 | width: 64rpx; 22 | height: 64rpx; 23 | opacity: .6; 24 | border-radius: 50%; 25 | } 26 | 27 | .ft-content { 28 | position: absolute; 29 | bottom: 10%; 30 | width: 100%; 31 | text-align: center; 32 | } 33 | 34 | .btn-scan { 35 | color: #fff; 36 | margin: 0 40rpx; 37 | padding: 24rpx; 38 | border-radius: 500rpx; 39 | background-color: rgba(0, 0,0, .6); 40 | } -------------------------------------------------------------------------------- /golang/share_car/pages/register/index.js: -------------------------------------------------------------------------------- 1 | // pages/register/index.js 2 | Page({ 3 | 4 | /** 5 | * 页面的初始数据 6 | */ 7 | data: { 8 | licImage: null, 9 | status: 'NONE' 10 | }, 11 | 12 | /** 13 | * 生命周期函数--监听页面加载 14 | */ 15 | onLoad: function (options) { 16 | 17 | }, 18 | onChooseLic() { 19 | wx.chooseMedia({ 20 | count: 1, 21 | mediaType: ['image',], 22 | sourceType: ['album', 'camera'], 23 | maxDuration: 30, 24 | camera: 'back', 25 | success: (res) => { 26 | console.log(res.tempFiles) 27 | this.setData({ 28 | licImage: res.tempFiles[0].tempFilePath, 29 | }) 30 | } 31 | }) 32 | }, 33 | onSubit() { 34 | wx.showLoading({ 35 | mark: true, 36 | title: '上传中' 37 | }) 38 | setTimeout( ()=> { 39 | wx.hideLoading() 40 | this.setData({ 41 | status: 'PENDING' 42 | }) 43 | }, 2000) 44 | } 45 | }) -------------------------------------------------------------------------------- /golang/share_car/pages/register/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "注册", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /golang/share_car/pages/register/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 上传驾照 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /golang/share_car/pages/register/index.wxss: -------------------------------------------------------------------------------- 1 | .no-lic { 2 | width: 600rpx; 3 | height: 600rpx; 4 | margin-top: 24rpx; 5 | display: flex; 6 | justify-content: center; 7 | align-items: center; 8 | margin-left: 76rpx; 9 | border-radius: 8rpx; 10 | color: #fff; 11 | background-color: rgba(0, 0, 0, .7); 12 | } 13 | .lic-img { 14 | width: 600rpx; 15 | height: 600rpx; 16 | margin-left: 76rpx; 17 | margin-top: 24rpx; 18 | } 19 | 20 | .opt-content { 21 | text-align: center; 22 | margin-top: 12rpx; 23 | } -------------------------------------------------------------------------------- /golang/share_car/pages/test/index.js: -------------------------------------------------------------------------------- 1 | // pages/test/index.js 2 | Page({ 3 | 4 | /** 5 | * 页面的初始数据 6 | */ 7 | data: { 8 | list:[ 9 | ['Google', 15, 'red'], 10 | ['JD', 12], 11 | ['GoogleA', 10], 12 | ['Alibaba', 7], 13 | ['Baidu', 6], 14 | ['NetEase', 4], 15 | ['Youku', 4], 16 | ['Meituan', 3], 17 | ['Douban', 3], 18 | ] 19 | }, 20 | 21 | /** 22 | * 生命周期函数--监听页面加载 23 | */ 24 | onLoad(options) { 25 | 26 | }, 27 | 28 | /** 29 | * 生命周期函数--监听页面初次渲染完成 30 | */ 31 | onReady() { 32 | 33 | }, 34 | 35 | /** 36 | * 生命周期函数--监听页面显示 37 | */ 38 | onShow() { 39 | 40 | }, 41 | 42 | /** 43 | * 生命周期函数--监听页面隐藏 44 | */ 45 | onHide() { 46 | 47 | }, 48 | 49 | /** 50 | * 生命周期函数--监听页面卸载 51 | */ 52 | onUnload() { 53 | 54 | }, 55 | 56 | /** 57 | * 页面相关事件处理函数--监听用户下拉动作 58 | */ 59 | onPullDownRefresh() { 60 | 61 | }, 62 | 63 | /** 64 | * 页面上拉触底事件的处理函数 65 | */ 66 | onReachBottom() { 67 | 68 | }, 69 | 70 | /** 71 | * 用户点击右上角分享 72 | */ 73 | onShareAppMessage() { 74 | 75 | } 76 | }) -------------------------------------------------------------------------------- /golang/share_car/pages/test/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": { 3 | "w-c": "/components/word-cloud/index" 4 | } 5 | } -------------------------------------------------------------------------------- /golang/share_car/pages/test/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /golang/share_car/pages/test/index.wxss: -------------------------------------------------------------------------------- 1 | /* pages/test/index.wxss */ -------------------------------------------------------------------------------- /golang/share_car/pages/unlock/index.js: -------------------------------------------------------------------------------- 1 | // pages/unlock/index.js 2 | Page({ 3 | 4 | /** 5 | * 页面的初始数据 6 | */ 7 | data: { 8 | 9 | }, 10 | 11 | /** 12 | * 生命周期函数--监听页面加载 13 | */ 14 | onLoad: function (options) { 15 | 16 | }, 17 | 18 | onUnlock() { 19 | 20 | 21 | wx.getLocation({ 22 | type:'gcj02', 23 | success:res=>{ 24 | // this.setData({ 25 | // longitude: res.longitude, 26 | // latitude: res.latitude 27 | // }) 28 | wx.showLoading({ 29 | mark: true, 30 | title: '开锁中' 31 | }) 32 | setTimeout(() => { 33 | wx.redirectTo({ 34 | url: '/pages/driving/index',}) 35 | wx.hideLoading() 36 | }, 2000) 37 | }, 38 | fail: ()=> { 39 | wx.showToast( 40 | { 41 | title: '授权定位', 42 | icon: 'none', 43 | } 44 | ) 45 | } 46 | }) 47 | 48 | 49 | } 50 | }) -------------------------------------------------------------------------------- /golang/share_car/pages/unlock/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "解锁", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /golang/share_car/pages/unlock/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 驾驶安全是用户的责任 7 | 请将车辆停放在正确的车位内 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /golang/share_car/pages/unlock/index.wxss: -------------------------------------------------------------------------------- 1 | .content { 2 | padding-top: 24rpx; 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | height: 100vh; 7 | box-sizing: border-box; 8 | } 9 | .icon { 10 | width: 400rpx; 11 | height: 400rpx; 12 | } 13 | .desc { 14 | flex: 1; 15 | } 16 | .desc .txt { 17 | text-align: center; 18 | } 19 | .ft-content { 20 | flex: 1; 21 | } -------------------------------------------------------------------------------- /golang/share_car/project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件,详见文档:%s", 3 | "packOptions": { 4 | "ignore": [], 5 | "include": [] 6 | }, 7 | "setting": { 8 | "urlCheck": true, 9 | "es6": true, 10 | "enhance": true, 11 | "postcss": true, 12 | "preloadBackgroundData": false, 13 | "minified": true, 14 | "newFeature": false, 15 | "coverView": true, 16 | "nodeModules": false, 17 | "autoAudits": false, 18 | "showShadowRootInWxmlPanel": true, 19 | "scopeDataCheck": false, 20 | "uglifyFileName": false, 21 | "checkInvalidKey": true, 22 | "checkSiteMap": true, 23 | "uploadWithSourceMap": true, 24 | "compileHotReLoad": false, 25 | "lazyloadPlaceholderEnable": false, 26 | "useMultiFrameRuntime": false, 27 | "useApiHook": false, 28 | "useApiHostProcess": false, 29 | "babelSetting": { 30 | "ignore": [], 31 | "disablePlugins": [], 32 | "outputPath": "" 33 | }, 34 | "useIsolateContext": false, 35 | "userConfirmedBundleSwitch": false, 36 | "packNpmManually": false, 37 | "packNpmRelationList": [], 38 | "minifyWXSS": true, 39 | "disableUseStrict": false, 40 | "minifyWXML": true, 41 | "showES6CompileOption": false, 42 | "useCompilerPlugins": false, 43 | "ignoreUploadUnusedFiles": true 44 | }, 45 | "compileType": "miniprogram", 46 | "libVersion": "2.24.2", 47 | "appid": "wx5b8c0dadaa80810d", 48 | "projectname": "share_car", 49 | "editorSetting": { 50 | "tabIndent": "insertSpaces", 51 | "tabSize": 2 52 | }, 53 | "cloudfunctionTemplateRoot": "cloudfunctionTemplate", 54 | "condition": { 55 | "search": { 56 | "list": [] 57 | }, 58 | "conversation": { 59 | "list": [] 60 | }, 61 | "game": { 62 | "list": [] 63 | }, 64 | "plugin": { 65 | "list": [] 66 | }, 67 | "gamePlugin": { 68 | "list": [] 69 | }, 70 | "miniprogram": { 71 | "list": [] 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /golang/share_car/project.private.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "setting": { 3 | "compileHotReLoad": false, 4 | "useIsolateContext": false 5 | }, 6 | "condition": { 7 | "miniprogram": { 8 | "list": [ 9 | { 10 | "name": "", 11 | "pathName": "pages/register/index", 12 | "query": "", 13 | "launchMode": "default", 14 | "scene": null 15 | }, 16 | { 17 | "name": "", 18 | "pathName": "pages/unlock/index", 19 | "query": "", 20 | "launchMode": "default", 21 | "scene": null 22 | }, 23 | { 24 | "name": "", 25 | "pathName": "pages/driving/index", 26 | "query": "", 27 | "launchMode": "default", 28 | "scene": null 29 | } 30 | ] 31 | } 32 | }, 33 | "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", 34 | "projectname": "share_car" 35 | } -------------------------------------------------------------------------------- /golang/share_car/sitemap.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", 3 | "rules": [{ 4 | "action": "allow", 5 | "page": "*" 6 | }] 7 | } -------------------------------------------------------------------------------- /html5-Qrcode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 二维码扫描 8 | 9 | 10 | 11 | 12 |
13 |
扫描二维码1 14 | 15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /html5-Qrcode/lib/my.css: -------------------------------------------------------------------------------- 1 | .jsbridge { 2 | height: 200px; 3 | width: 200px; 4 | background-color: red; 5 | } 6 | 7 | .upimg { 8 | height: 200px; 9 | width: 200px; 10 | background-color: green; 11 | margin-bottom: 50px; 12 | } 13 | 14 | .qr-btn{ 15 | width:200px; 16 | height:50px; 17 | background-color:#157EFB ; 18 | line-height: 50px; 19 | text-align: center; 20 | color:#fff; 21 | border-radius: 10% 10%; 22 | margin-bottom:10px; 23 | } 24 | 25 | input[node-type=jsbridge]{ 26 | visibility: hidden; 27 | } -------------------------------------------------------------------------------- /i18n-processor/README.md: -------------------------------------------------------------------------------- 1 | # i18n-processor 2 | 3 | 一个用于处理 React 项目国际化的命令行工具,支持 AST 和正则表达式两种处理模式。 4 | 5 | ## 特性 6 | 7 | - 支持 AST 和正则表达式两种处理模式 8 | - 支持处理 .js、.jsx、.ts、.tsx 文件 9 | - 支持批量处理整个目录 10 | - 支持自定义输出目录 11 | - 支持变量插值的国际化处理 12 | 13 | ## 安装 14 | 15 | ```bash 16 | npm install -g i18n-processor 17 | ``` 18 | ## 使用 19 | ```bash 20 | i18n-processor --help 21 | ``` 22 | ## 选项 23 | - `-f, --file `: 指定要处理的文件或目录 24 | - `-d, --dir `: '要处理的目录路径 25 | - `-o, --output `: 指定输出目录,默认为当前目录 26 | 27 | -------------------------------------------------------------------------------- /i18n-processor/bin/i18n-processor.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('../dist/cli.js'); -------------------------------------------------------------------------------- /i18n-processor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "i18n-processor", 3 | "version": "1.0.5", 4 | "description": "一个用于处理 React 项目国际化的命令行工具", 5 | "main": "dist/cli.js", 6 | "types": "dist/index.d.ts", 7 | "bin": { 8 | "i18n-processor": "./bin/i18n-processor.js" 9 | }, 10 | "files": [ 11 | "dist" 12 | ], 13 | "scripts": { 14 | "build": "tsc", 15 | "test": "jest", 16 | "lint": "eslint src --ext .ts", 17 | "format": "prettier --write \"src/**/*.ts\"" 18 | }, 19 | "keywords": [ 20 | "i18n", 21 | "react", 22 | "internationalization", 23 | "cli" 24 | ], 25 | "author": "wtechtec", 26 | "repository": { 27 | "type": "git", 28 | "url": "git+https://github.com/WtecHtec/WorkNotes.git" 29 | }, 30 | "homepage": "https://github.com/WtecHtec/WorkNotes/tree/master/i18n-processor", 31 | "license": "MIT", 32 | "dependencies": { 33 | "@babel/parser": "^7.x", 34 | "@babel/traverse": "^7.x", 35 | "@babel/generator": "^7.x", 36 | "@babel/types": "^7.x", 37 | "commander": "^8.x" 38 | }, 39 | "devDependencies": { 40 | "@types/node": "^16.x", 41 | "@types/babel__traverse": "^7.x", 42 | "typescript": "^4.x", 43 | "ts-node": "^10.x", 44 | "jest": "^27.x", 45 | "@types/jest": "^27.x", 46 | "eslint": "^8.x", 47 | "@typescript-eslint/parser": "^5.x", 48 | "@typescript-eslint/eslint-plugin": "^5.x", 49 | "prettier": "^2.x" 50 | } 51 | } -------------------------------------------------------------------------------- /i18n-processor/src/cli.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { program } from 'commander'; 3 | import { processFile, processDirectory } from './core/processor'; 4 | import { ensureOutputDir } from './utils/file'; 5 | 6 | const { version } = require('../package.json'); 7 | 8 | program 9 | .version(version) 10 | .description('一个用于处理 React 项目国际化的命令行工具') 11 | .option('-d, --dir ', '要处理的目录路径') 12 | .option('-f, --file ', '要处理的单个文件路径') 13 | .option('-o, --output ', '输出目录路径') 14 | .option('-m, --mode ', '处理模式: ast 或 regex', 'ast') 15 | .option('-v, --verbose', '显示详细日志') 16 | .on('--help', () => { 17 | console.log(''); 18 | console.log('示例:'); 19 | console.log(' $ i18n-processor -f src/App.tsx -o dist/i18n'); 20 | console.log(' $ i18n-processor -d src/pages -o dist/i18n -m regex'); 21 | console.log(''); 22 | console.log('支持的文件类型:'); 23 | console.log(' .js, .jsx, .ts, .tsx'); 24 | }); 25 | 26 | program.parse(process.argv); 27 | 28 | const options = program.opts(); 29 | 30 | async function main() { 31 | try { 32 | if (!options.dir && !options.file) { 33 | console.error('错误: 请指定目录(-d) 或文件路径(-f)'); 34 | process.exit(1); 35 | } 36 | 37 | if (options.mode !== 'ast' && options.mode !== 'regex') { 38 | console.error('错误: 处理模式必须是 "ast" 或 "regex"'); 39 | process.exit(1); 40 | } 41 | 42 | if (options.output) { 43 | await ensureOutputDir(options.output); 44 | } 45 | 46 | if (options.file) { 47 | await processFile(options.file, options as any); 48 | } 49 | 50 | if (options.dir) { 51 | await processDirectory(options.dir, options as any); 52 | } 53 | 54 | } catch (error) { 55 | console.error('处理过程中发生错误:', error); 56 | process.exit(1); 57 | } 58 | } 59 | 60 | main(); -------------------------------------------------------------------------------- /i18n-processor/src/core/processor.ts: -------------------------------------------------------------------------------- 1 | import { processWithAST } from './ast'; 2 | import { promises as fs } from 'fs'; 3 | import path from 'path'; 4 | import { ProcessOptions } from './types'; 5 | import { ensureOutputDir, isValidFile, getAllFiles, ensureFileExists } from '../utils/file'; 6 | 7 | export async function processFile(filePath: string, options: ProcessOptions) { 8 | try { 9 | if (!await isValidFile(filePath)) { 10 | throw new Error(`无效的文件: ${filePath}`); 11 | } 12 | console.log("处理文件中:::") 13 | const content = await fs.readFile(filePath, 'utf8'); 14 | const processor = options.mode === 'ast' ? processWithAST : processWithAST; 15 | 16 | const result = await processor(content); 17 | const outputPath = options.output 18 | ? path.join(options.output, path.relative(process.cwd(), filePath)) 19 | : filePath; 20 | if (result.hasModification) { 21 | // 确保输出目录存在 22 | await ensureOutputDir(path.dirname(outputPath)); 23 | // 确保输出文件存在 24 | await ensureFileExists(outputPath); 25 | // 写入文件 26 | await fs.writeFile(outputPath, result.code, 'utf8'); 27 | console.log(`已处理文件: ${outputPath}`); 28 | } else { 29 | console.log(`文件没有内容可修改.`); 30 | } 31 | } catch (error) { 32 | console.error(`处理文件 ${filePath} 时出错:`, error); 33 | throw error; 34 | } 35 | } 36 | 37 | export async function processDirectory(dirPath: string, options: ProcessOptions) { 38 | try { 39 | const files = await getAllFiles(dirPath); 40 | 41 | for (const file of files) { 42 | await processFile(file, options); 43 | } 44 | } catch (error) { 45 | console.error(`处理目录 ${dirPath} 时出错:`, error); 46 | throw error; 47 | } 48 | } -------------------------------------------------------------------------------- /i18n-processor/src/core/types.ts: -------------------------------------------------------------------------------- 1 | export interface ProcessOptions { 2 | mode: 'ast' | 'regex'; 3 | output?: string; 4 | verbose?: boolean; 5 | } 6 | 7 | export interface ProcessResult { 8 | code: string; 9 | hasModification: boolean; 10 | } 11 | 12 | export interface FileConfig { 13 | input: string; 14 | output?: string; 15 | } -------------------------------------------------------------------------------- /i18n-processor/src/utils/common.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/i18n-processor/src/utils/common.ts -------------------------------------------------------------------------------- /i18n-processor/src/utils/file.ts: -------------------------------------------------------------------------------- 1 | import { promises as fs } from 'fs'; 2 | import path from 'path'; 3 | 4 | export async function ensureOutputDir(outputPath: string): Promise { 5 | try { 6 | // 确保目录存在,使用绝对路径 7 | const absolutePath = path.resolve(outputPath); 8 | await fs.mkdir(path.dirname(absolutePath), { recursive: true }); 9 | } catch (error) { 10 | if ((error as NodeJS.ErrnoException).code !== 'EEXIST') { 11 | throw error; 12 | } 13 | } 14 | } 15 | 16 | export async function ensureFileExists(filePath: string): Promise { 17 | try { 18 | // 使用绝对路径 19 | const absolutePath = path.resolve(filePath); 20 | // 确保父目录存在 21 | await ensureOutputDir(absolutePath); 22 | // 检查文件是否存在 23 | await fs.access(absolutePath); 24 | } catch { 25 | // 文件不存在,创建空文件 26 | const absolutePath = path.resolve(filePath); 27 | await fs.writeFile(absolutePath, '', 'utf8'); 28 | } 29 | } 30 | 31 | 32 | 33 | export async function isValidFile(filePath: string): Promise { 34 | try { 35 | const stat = await fs.stat(filePath); 36 | return stat.isFile() && /\.(js|jsx|ts|tsx)$/.test(filePath); 37 | } catch { 38 | return false; 39 | } 40 | } 41 | 42 | export async function getAllFiles(dirPath: string): Promise { 43 | const files: string[] = []; 44 | 45 | async function traverse(dir: string) { 46 | const entries = await fs.readdir(dir, { withFileTypes: true }); 47 | 48 | for (const entry of entries) { 49 | const fullPath = path.join(dir, entry.name); 50 | 51 | if (entry.isDirectory()) { 52 | await traverse(fullPath); 53 | } else if (entry.isFile() && /\.(js|jsx|ts|tsx)$/.test(entry.name)) { 54 | files.push(fullPath); 55 | } 56 | } 57 | } 58 | 59 | await traverse(dirPath); 60 | return files; 61 | } -------------------------------------------------------------------------------- /i18n-processor/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "outDir": "./dist", 6 | "rootDir": "./src", 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "declaration": true 12 | }, 13 | "include": ["src"], 14 | "exclude": ["node_modules", "dist", "test"] 15 | } -------------------------------------------------------------------------------- /mcp-servers/mcp-tools.js: -------------------------------------------------------------------------------- 1 | export function parseToolUse(content, mcpTools) { 2 | if (!content || !mcpTools || mcpTools.length === 0) { 3 | return [] 4 | } 5 | const toolUsePattern = 6 | /([\s\S]*?)([\s\S]*?)<\/name>([\s\S]*?)([\s\S]*?)<\/arguments>([\s\S]*?)<\/tool_use>/g 7 | const tools = [] 8 | let match 9 | let idx = 0 10 | // Find all tool use blocks 11 | while ((match = toolUsePattern.exec(content)) !== null) { 12 | // const fullMatch = match[0] 13 | const toolName = match[2].trim() 14 | const toolArgs = match[4].trim() 15 | 16 | // Try to parse the arguments as JSON 17 | let parsedArgs 18 | try { 19 | parsedArgs = JSON.parse(toolArgs) 20 | } catch (error) { 21 | // If parsing fails, use the string as is 22 | parsedArgs = toolArgs 23 | } 24 | // console.log(`Parsed arguments for tool "${toolName}":`, parsedArgs) 25 | const mcpTool = mcpTools.find((tool) => tool.name === toolName) 26 | if (!mcpTool) { 27 | console.error(`Tool "${toolName}" not found in MCP tools`) 28 | continue 29 | } 30 | 31 | // Add to tools array 32 | tools.push({ 33 | id: `${toolName}-${idx++}`, // Unique ID for each tool use 34 | tool: { 35 | ...mcpTool, 36 | inputSchema: parsedArgs 37 | }, 38 | status: 'pending' 39 | }) 40 | 41 | // Remove the tool use block from the content 42 | // content = content.replace(fullMatch, '') 43 | } 44 | return tools 45 | } -------------------------------------------------------------------------------- /mcp-servers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodeserver", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "keywords": [], 9 | "author": "", 10 | "license": "ISC", 11 | "description": "", 12 | "dependencies": { 13 | "@google/generative-ai": "^0.21.0", 14 | "@nut-tree/nut-js": "^3.1.2", 15 | "cheerio": "^1.0.0", 16 | "dgram": "^1.0.1", 17 | "dotenv": "^16.5.0", 18 | "epub": "^1.2.1", 19 | "express": "^5.1.0", 20 | "pdf-lib": "^1.17.1", 21 | "pdf-parse": "^1.1.1", 22 | "robotjs": "^0.6.0", 23 | "sentence-splitter": "^5.0.0", 24 | "undici": "^7.8.0", 25 | "ws": "^8.18.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /mcp-servers/prompts/gemini.js: -------------------------------------------------------------------------------- 1 | export const prompt = ``; -------------------------------------------------------------------------------- /mcp-weather-server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | *.log 4 | .env* -------------------------------------------------------------------------------- /mcp-weather-server/README.md: -------------------------------------------------------------------------------- 1 | # mcp-weather-server MCP Server 2 | 3 | A Model Context Protocol server 4 | 5 | This is a TypeScript-based MCP server that implements a simple notes system. It demonstrates core MCP concepts by providing: 6 | 7 | - Resources representing text notes with URIs and metadata 8 | - Tools for creating new notes 9 | - Prompts for generating summaries of notes 10 | 11 | ## Features 12 | 13 | ### Resources 14 | - List and access notes via `note://` URIs 15 | - Each note has a title, content and metadata 16 | - Plain text mime type for simple content access 17 | 18 | ### Tools 19 | - `create_note` - Create new text notes 20 | - Takes title and content as required parameters 21 | - Stores note in server state 22 | 23 | ### Prompts 24 | - `summarize_notes` - Generate a summary of all stored notes 25 | - Includes all note contents as embedded resources 26 | - Returns structured prompt for LLM summarization 27 | 28 | ## Development 29 | 30 | Install dependencies: 31 | ```bash 32 | npm install 33 | ``` 34 | 35 | Build the server: 36 | ```bash 37 | npm run build 38 | ``` 39 | 40 | For development with auto-rebuild: 41 | ```bash 42 | npm run watch 43 | ``` 44 | 45 | ## Installation 46 | 47 | To use with Claude Desktop, add the server config: 48 | 49 | On MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json` 50 | On Windows: `%APPDATA%/Claude/claude_desktop_config.json` 51 | 52 | ```json 53 | { 54 | "mcpServers": { 55 | "mcp-weather-server": { 56 | "command": "/path/to/mcp-weather-server/build/index.js" 57 | } 58 | } 59 | } 60 | ``` 61 | 62 | ### Debugging 63 | 64 | Since MCP servers communicate over stdio, debugging can be challenging. We recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector), which is available as a package script: 65 | 66 | ```bash 67 | npm run inspector 68 | ``` 69 | 70 | The Inspector will provide a URL to access debugging tools in your browser. 71 | -------------------------------------------------------------------------------- /mcp-weather-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mcp-weather-server", 3 | "version": "0.1.0", 4 | "description": "A Model Context Protocol server", 5 | "private": true, 6 | "type": "module", 7 | "bin": { 8 | "mcp-weather-server": "./build/index.js" 9 | }, 10 | "files": [ 11 | "build" 12 | ], 13 | "scripts": { 14 | "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"", 15 | "prepare": "npm run build", 16 | "watch": "tsc --watch", 17 | "inspector": "npx @modelcontextprotocol/inspector build/index.js" 18 | }, 19 | "dependencies": { 20 | "@modelcontextprotocol/sdk": "0.6.0" 21 | }, 22 | "devDependencies": { 23 | "@types/node": "^20.11.24", 24 | "typescript": "^5.3.3" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /mcp-weather-server/src/WeatherServer/mock.ts: -------------------------------------------------------------------------------- 1 | import { WeatherData } from "./type.js"; 2 | 3 | 4 | export const weatherData: { [id: string]: WeatherData } = { 5 | "beijing": { 6 | location: "北京", 7 | temperature: 25, 8 | condition: "晴朗", 9 | humidity: 45, 10 | windSpeed: 10, 11 | forecast: "未来三天天气晴朗,气温在22-28度之间" 12 | }, 13 | "shanghai": { 14 | location: "上海", 15 | temperature: 28, 16 | condition: "多云", 17 | humidity: 65, 18 | windSpeed: 15, 19 | forecast: "未来三天多云转阴,有小雨,气温在24-30度之间" 20 | }, 21 | "guangzhou": { 22 | location: "广州", 23 | temperature: 32, 24 | condition: "雷阵雨", 25 | humidity: 80, 26 | windSpeed: 12, 27 | forecast: "未来三天有雷阵雨,气温在28-34度之间" 28 | } 29 | }; -------------------------------------------------------------------------------- /mcp-weather-server/src/WeatherServer/type.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 天气数据类型 3 | */ 4 | type WeatherData = { 5 | location: string, 6 | temperature: number, 7 | condition: string, 8 | humidity: number, 9 | windSpeed: number, 10 | forecast: string 11 | }; 12 | 13 | export { 14 | WeatherData 15 | } -------------------------------------------------------------------------------- /mcp-weather-server/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 3 | import WeatherServer from "./WeatherServer/index.js"; 4 | async function main() { 5 | new WeatherServer().run(); 6 | } 7 | 8 | main().catch((error) => { 9 | console.error("Server error:", error); 10 | process.exit(1); 11 | }); -------------------------------------------------------------------------------- /mcp-weather-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "outDir": "./build", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true 12 | }, 13 | "include": ["src/**/*"], 14 | "exclude": ["node_modules"] 15 | } 16 | -------------------------------------------------------------------------------- /mobileEvent/README.md: -------------------------------------------------------------------------------- 1 | EventUtilSlider.js (前端js 实现移动端点击长按上下左右滑事件) 2 | 使用: 3 | 4 | 5 | 6 | 7 | 8 | //获取dom 9 | let domContent = document.querySelector('#main'); 10 | //定义各类事件,为了可以解除事件绑定,事件回调不使用匿名函数 11 | function handleClick() { 12 | alert('点击事件'); 13 | } 14 | //绑定点击事件 15 | EventUtil.bindEvent(domContent, 'click', handleClick); 16 | 附录: 17 | swipeleft是左滑事件,swiperight是右滑事件,slideup是上滑事件,slidedown下滑事件,click点击事件,longpress长按点击事件 -------------------------------------------------------------------------------- /node-websocket/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /node-websocket/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "websocket", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /node-websocket/server.js: -------------------------------------------------------------------------------- 1 | const MyWebSocket = require('./ws'); 2 | const ws = new MyWebSocket({ port: 4299 }); 3 | 4 | ws.on('data', (data) => { 5 | console.log('receive data:' + data); 6 | setInterval(() => { 7 | ws.send(data + ' ' + Date.now()); 8 | }, 2000) 9 | }); 10 | 11 | ws.on('close', (code, reason) => { 12 | console.log('close:', code, reason); 13 | }); -------------------------------------------------------------------------------- /online_code/online_run.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 在线运行代码 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 52 | 53 | -------------------------------------------------------------------------------- /protobf-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "protobf-ex", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "proto": "pbjs -t json-module -w commonjs -o ./proto/proto.js ./proto/*.proto", 9 | "proto-es6": "pbjs ./proto/user.proto -es6 ./proto/proto.js " 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "axios": "^1.5.0", 16 | "cors": "^2.8.5", 17 | "express": "^4.18.2" 18 | }, 19 | "dependencies": { 20 | "protobufjs": "6.11" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /protobf-demo/proto/proto.js: -------------------------------------------------------------------------------- 1 | /*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/ 2 | "use strict"; 3 | 4 | var $protobuf = require("protobufjs/light"); 5 | 6 | var $root = ($protobuf.roots["default"] || ($protobuf.roots["default"] = new $protobuf.Root())) 7 | .addJSON({ 8 | userpackage: { 9 | nested: { 10 | User: { 11 | fields: { 12 | name: { 13 | type: "string", 14 | id: 0 15 | }, 16 | age: { 17 | type: "int64", 18 | id: 1 19 | } 20 | } 21 | } 22 | } 23 | } 24 | }); 25 | 26 | module.exports = $root; 27 | -------------------------------------------------------------------------------- /protobf-demo/proto/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package userpackage; 3 | 4 | message User { 5 | string name = 0; 6 | int64 age = 1; 7 | } -------------------------------------------------------------------------------- /protobf-demo/server.js: -------------------------------------------------------------------------------- 1 | // const axios = require('axios'); 2 | const express = require('express'); 3 | // const protobuf = require('protobufjs'); 4 | const protoRoot = require('./proto/proto') 5 | const cors = require('cors'); 6 | 7 | const app = express(); 8 | 9 | app.use(cors()); 10 | 11 | run().catch(err => console.log(err)); 12 | 13 | async function run() { 14 | // const root = await protobuf.load('./proto/user.proto'); 15 | 16 | const doc = { name: 'Bill', age: 30 }; 17 | const User = protoRoot.lookupType('userpackage.User'); 18 | 19 | app.get('/user', function(req, res) { 20 | res.send(User.encode(doc).finish()); 21 | }); 22 | 23 | // 在decode之前需要用raw中间件处理一遍protobuf数据 24 | app.post('/user', express.raw({ type: '*/*' }), function(req, res) { 25 | // Assume `req.body` contains the protobuf as a utf8-encoded string 26 | const user = User.decode(Buffer.from(req.body)); 27 | Object.assign(doc, user); 28 | res.end(); 29 | }); 30 | 31 | await app.listen(3000); 32 | console.log('服务启动: http://127.0.0.1:3000') 33 | } 34 | -------------------------------------------------------------------------------- /proxy-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "proxy-web", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "express": "^4.18.2", 14 | "http-proxy-middleware": "^2.0.6" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /pyRAG/.env: -------------------------------------------------------------------------------- 1 | GOOGLE_API_KEY= -------------------------------------------------------------------------------- /pyRAG/Embeddings.py: -------------------------------------------------------------------------------- 1 | # from openai import OpenAI 2 | from langchain.embeddings import HuggingFaceBgeEmbeddings 3 | import os 4 | # 加载环境变量 5 | from dotenv import load_dotenv, find_dotenv 6 | _ = load_dotenv(find_dotenv()) # 读取本地 .env 文件,里面定义了 OPENAI_API_KEY 7 | 8 | # client = OpenAI() 9 | 10 | 11 | # 加载中文embedding模型 开源模型 12 | bge_embeddings = HuggingFaceBgeEmbeddings(model_name="BAAI/bge-large-zh-v1.5") 13 | 14 | 15 | def get_embeddings(texts, model="text-embedding-3-small"): 16 | '''封装 OpenAI 的 Embedding 模型接口''' 17 | # print(texts) 18 | # print(model) 19 | '''open ai 提供的embedding 接口''' 20 | # data = client.embeddings.create(input=texts, model=model).data 21 | # return [x.embedding for x in data] 22 | '''huggingface 提供的embedding 接口''' 23 | data = bge_embeddings.embed_documents(texts) 24 | # print(data) 25 | return data 26 | -------------------------------------------------------------------------------- /pyRAG/MyVectorDBConnector.py: -------------------------------------------------------------------------------- 1 | import chromadb 2 | from chromadb.config import Settings 3 | 4 | class MyVectorDBConnector: 5 | def __init__(self, collection_name, embedding_fn): 6 | chroma_client = chromadb.Client(Settings(allow_reset=True)) 7 | 8 | # 为了演示,实际不需要每次 reset() 9 | chroma_client.reset() 10 | 11 | # 创建一个 collection 12 | self.collection = chroma_client.get_or_create_collection(name=collection_name) 13 | self.embedding_fn = embedding_fn 14 | 15 | def add_documents(self, documents): 16 | '''向 collection 中添加文档与向量''' 17 | self.collection.add( 18 | embeddings=self.embedding_fn(documents), # 每个文档的向量 19 | documents=documents, # 文档的原文 20 | ids=[f"id{i}" for i in range(len(documents))] # 每个文档的 id 21 | ) 22 | 23 | def search(self, query, top_n): 24 | '''检索向量数据库''' 25 | results = self.collection.query( 26 | query_embeddings=self.embedding_fn([query]), 27 | n_results=top_n 28 | ) 29 | return results 30 | -------------------------------------------------------------------------------- /pyRAG/PDFFileLoader.py: -------------------------------------------------------------------------------- 1 | from pdfminer.high_level import extract_pages 2 | from pdfminer.layout import LTTextContainer 3 | 4 | class PDFFileLoader(): 5 | def __init__(self, file) -> None: 6 | self.paragraphs = self.extract_text_from_pdf(file) 7 | # i = 1 8 | # for para in self.paragraphs[:10]: 9 | # print(f"========= 第{i}段 ==========") 10 | # print(para+"\n") 11 | # i += 1 12 | 13 | def getParagraphs(self): 14 | return self.paragraphs 15 | 16 | ################################# 文档的加载与切割 ############################ 17 | def extract_text_from_pdf(self, filename, page_numbers=None): 18 | '''从 PDF 文件中(按指定页码)提取文字''' 19 | paragraphs = [] 20 | buffer = '' 21 | full_text = '' 22 | # 提取全部文本 23 | for i, page_layout in enumerate(extract_pages(filename)): 24 | # 如果指定了页码范围,跳过范围外的页 25 | if page_numbers is not None and i not in page_numbers: 26 | continue 27 | for element in page_layout: 28 | if isinstance(element, LTTextContainer): 29 | full_text += element.get_text() + '\n' 30 | 31 | # 段落分割 32 | lines = full_text.split('。\n') 33 | for text in lines: 34 | buffer = text.replace('\n', ' ') 35 | 36 | if buffer: 37 | paragraphs.append(buffer) 38 | buffer = '' 39 | row_count = 0 40 | 41 | if buffer: 42 | paragraphs.append(buffer) 43 | return paragraphs 44 | 45 | -------------------------------------------------------------------------------- /pyRAG/a-practical-guide-to-building-agents.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/pyRAG/a-practical-guide-to-building-agents.pdf -------------------------------------------------------------------------------- /pyRAG/index.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | from dotenv import load_dotenv, find_dotenv 4 | 5 | from langchain.schema.runnable import RunnableMap 6 | from langchain.prompts import ChatPromptTemplate 7 | from langchain.schema.output_parser import StrOutputParser 8 | from langchain_google_genai import ChatGoogleGenerativeAI 9 | 10 | 11 | from PDFFileLoader import PDFFileLoader 12 | from Embeddings import get_embeddings 13 | from MyVectorDBConnector import MyVectorDBConnector 14 | 15 | _ = load_dotenv(find_dotenv()) #加载 .env文件 16 | 17 | pdf_loader = PDFFileLoader("./a-practical-guide-to-building-agents.pdf") 18 | # 创建一个向量数据库对象 19 | vector_db = MyVectorDBConnector("demo", get_embeddings) 20 | vector_db.add_documents(pdf_loader.getParagraphs()) 21 | 22 | 23 | user_query = "what is AI agent?" 24 | results = vector_db.search(user_query, 3) # 3是指查询出最相近的3块文本 25 | # for para in results['documents'][0]: 26 | # print(para+"\n\n") 27 | 28 | #创建model 29 | model = ChatGoogleGenerativeAI(model="gemini-1.5-flash") 30 | 31 | #创建prompt模板 32 | template = """ 33 | 你是一个问答机器人。 34 | 你的任务是根据下述给定的已知信息回答用户问题。 35 | 确保你的回复完全依据下述已知信息。不要编造答案。 36 | 如果下述已知信息不足以回答用户的问题,可以结合你的语言大模型的能力回答。 37 | 38 | 已知信息: 39 | {context} 40 | 41 | 用户问: 42 | {question} 43 | """ 44 | 45 | #由模板生成prompt 46 | prompt = ChatPromptTemplate.from_template(template) 47 | 48 | chain = RunnableMap({ 49 | "context": lambda x: "\n".join(vector_db.search(x["question"], 3)['documents'][0]), 50 | "question": lambda x: x["question"] 51 | }) | prompt | model | StrOutputParser() 52 | 53 | # 添加这行代码来打印prompt的内容 54 | print("最终的prompt内容:", prompt.invoke({"context": "\n".join(vector_db.search(user_query, 3)['documents'][0]), "question": user_query})) 55 | 56 | response = chain.invoke({"question": user_query}) 57 | 58 | print("返回结果:", response) -------------------------------------------------------------------------------- /pyRAG/如何让 LLM 应用性能登峰造极.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/pyRAG/如何让 LLM 应用性能登峰造极.pdf -------------------------------------------------------------------------------- /pyRTC/.env.exp: -------------------------------------------------------------------------------- 1 | XUNFEI_API_KEY= -------------------------------------------------------------------------------- /pyRTC/models/README.md: -------------------------------------------------------------------------------- 1 | ## ASR 2 | 下载模型放置于`models/asr`目录下 3 | 4 | (1) Download the test model 5 | 6 | wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2 7 | 8 | (2) Download rule fst 9 | 10 | wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst 11 | 12 | ## TTS 13 | 下载模型放置于`models/tts`目录下 14 | 15 | ``` 16 | wget https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-icefall-zh-aishell3.tar.bz2 17 | ``` -------------------------------------------------------------------------------- /pyRTC/requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi 2 | uvicorn[standard] 3 | websockets 4 | python-dotenv 5 | httpx 6 | # STT/TTS: sherpa-onnx 7 | sherpa-onnx 8 | # 音频处理库 (用于格式转换) 9 | pydub 10 | numpy 11 | # WebRTC for Python 12 | aiortc 13 | av 14 | webrtcvad 15 | dotenv -------------------------------------------------------------------------------- /react-web-pro-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/react-web-pro-master.zip -------------------------------------------------------------------------------- /rrweb-demo/README.md: -------------------------------------------------------------------------------- 1 | #### 监听页面dom状态 2 | 当页面是已加载、载入完成状态,触发(Meta)快照, 随后判断页面是否存在Dom节点, 触发(FullSnapshot)快照 。 3 | ``` 4 | // 状态判断 5 | document.readyState === "interactive" || document.readyState === "complete" 6 | 7 | // 触发(Meta)快照 8 | wrapEvent({ 9 | type: EventType.Meta, 10 | data: { 11 | href: window.location.href, 12 | width: **, 13 | height:** 14 | } 15 | }) 16 | 17 | // 触发(FullSnapshot)快照 18 | wrapEvent({ 19 | type: EventType.FullSnapshot, 20 | data: { 21 | node, 22 | initialOffset: { 23 | left: **, 24 | top: ** 25 | } 26 | } 27 | }) 28 | 29 | ``` 30 | 31 | ### MutationObserver 32 | 33 | 开启 MutationObserver 监听 dom节点变化: 34 | 35 | ``` 36 | subtree boolean 元素下的所有子节点的添加删除、属性变化等 37 | attributes boolean 属性变化 38 | attributeFilter array 需要筛选的属性值数组 39 | attributeOldValue boolean 属性变化的旧值 40 | childList boolean 子孙节点的添加或删除 41 | characterData boolean 节点中值的变化监听 42 | characterDataOldValue boolean 节点中值的变化监听 43 | 44 | ``` 45 | 46 | ### addEventListener 47 | addEventListener 监听按钮点击、滚动、鼠标滑动等事件 48 | ``` 49 | addEventListener 50 | ``` 51 | 52 | ### hover 事件 53 | 54 | 监听 鼠标移动事件, 55 | 1、 js触发 hover 事件 56 | 2、hover 样式新增类名,缺点:外链css,存在问题 57 | 58 | -------------------------------------------------------------------------------- /rrweb-demo/demo/data.js: -------------------------------------------------------------------------------- 1 | const TEST_DATAS = [] -------------------------------------------------------------------------------- /rrweb-demo/demo/type.js: -------------------------------------------------------------------------------- 1 | const TYPES = { 2 | EVENT: 1, 3 | META: 2, 4 | DOM: 3, 5 | } 6 | 7 | let data = ".hover-text:hover {\n\t\t\tcolor: yellow;\n\t\t}\n\t.hover-text:hover {\n\t\t\tcolor: yellow;\n\t\t}\n\t" 8 | 9 | var HOVER_SELECTOR = /:hover/g; 10 | // var HOVER_SELECTOR_GLOBAL = new RegExp(HOVER_SELECTOR.source, "g"); 11 | const text = data.replace(HOVER_SELECTOR, '.hover') 12 | console.log(text) -------------------------------------------------------------------------------- /rrweb-demo/rrWeb-demo/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { browser: true, es2020: true }, 3 | extends: [ 4 | 'eslint:recommended', 5 | 'plugin:react/recommended', 6 | 'plugin:react/jsx-runtime', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 10 | settings: { react: { version: '18.2' } }, 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': 'warn', 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /rrweb-demo/rrWeb-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /rrweb-demo/rrWeb-demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /rrweb-demo/rrWeb-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rrweb-demo", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint src --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0", 15 | "rrweb": "^2.0.0-alpha.4", 16 | "rrweb-player": "^1.0.0-alpha.4" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^18.0.37", 20 | "@types/react-dom": "^18.0.11", 21 | "@vitejs/plugin-react": "^4.0.0", 22 | "eslint": "^8.38.0", 23 | "eslint-plugin-react": "^7.32.2", 24 | "eslint-plugin-react-hooks": "^4.6.0", 25 | "eslint-plugin-react-refresh": "^0.3.4", 26 | "vite": "^4.3.9" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /rrweb-demo/rrWeb-demo/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rrweb-demo/rrWeb-demo/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /rrweb-demo/rrWeb-demo/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | import { record, } from 'rrweb' 3 | import './App.css' 4 | import { eventDatas } from './data' 5 | import Replayer from 'rrweb-player'; 6 | import 'rrweb-player/dist/style.css'; 7 | import viteLogo from '/vite.svg' 8 | function App() { 9 | const [count, setCount] = useState(0) 10 | let events = []; 11 | 12 | useEffect(() => { 13 | record({ 14 | emit(event) { 15 | console.log(event) 16 | // 将 event 存入 events 数组中 17 | events.push(event); 18 | }, 19 | }); 20 | return () => { 21 | console.log('events===') 22 | } 23 | }) 24 | 25 | const handlePlay = () => { 26 | console.log('eventDatas===', eventDatas.length) 27 | const replayer = new Replayer({ 28 | target: document.body, // 可以自定义 DOM 元素 29 | // 配置项 30 | props: { 31 | events: eventDatas, 32 | }, 33 | }); 34 | 35 | // 播放 36 | replayer.play(); 37 | } 38 | return ( 39 | <> 40 | Vite logo 41 |

Vite + React

42 |
43 | 46 | 49 | 52 |

53 | Edit src/App.jsx and save to test HMR 54 |

55 |
56 |

57 | Click on the Vite and React logos to learn more 58 |

59 | 60 | ) 61 | } 62 | 63 | export default App 64 | -------------------------------------------------------------------------------- /rrweb-demo/rrWeb-demo/src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | a:hover { 23 | color: #535bf2; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | display: flex; 29 | place-items: center; 30 | min-width: 320px; 31 | min-height: 100vh; 32 | } 33 | 34 | h1 { 35 | font-size: 3.2em; 36 | line-height: 1.1; 37 | } 38 | 39 | button { 40 | border-radius: 8px; 41 | border: 1px solid transparent; 42 | padding: 0.6em 1.2em; 43 | font-size: 1em; 44 | font-weight: 500; 45 | font-family: inherit; 46 | background-color: #1a1a1a; 47 | cursor: pointer; 48 | transition: border-color 0.25s; 49 | } 50 | button:hover { 51 | border-color: #646cff; 52 | } 53 | button:focus, 54 | button:focus-visible { 55 | outline: 4px auto -webkit-focus-ring-color; 56 | } 57 | 58 | @media (prefers-color-scheme: light) { 59 | :root { 60 | color: #213547; 61 | background-color: #ffffff; 62 | } 63 | a:hover { 64 | color: #747bff; 65 | } 66 | button { 67 | background-color: #f9f9f9; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /rrweb-demo/rrWeb-demo/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | 6 | 7 | ReactDOM.createRoot(document.getElementById('root')).render( 8 | 9 | 10 | , 11 | ) 12 | -------------------------------------------------------------------------------- /rrweb-demo/rrWeb-demo/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /socketIoDemo/README.md: -------------------------------------------------------------------------------- 1 | https://juejin.im/post/6868989296817209357 -------------------------------------------------------------------------------- /socketIoDemo/client/dist/script.js: -------------------------------------------------------------------------------- 1 | function init(){ 2 | 3 | //estrelas 4 | 5 | var style = ["style1", "style2", "style3", "style4"]; 6 | var tam = ["tam1", "tam1", "tam1", "tam2", "tam3"]; 7 | var opacity = ["opacity1", "opacity1", "opacity1", "opacity2", "opacity2", "opacity3"]; 8 | 9 | function getRandomArbitrary(min, max) { 10 | return Math.floor(Math.random() * (max - min)) + min; 11 | } 12 | 13 | var estrela = ""; 14 | var qtdeEstrelas = 250; 15 | var noite = document.querySelector(".constelacao"); 16 | var widthWindow = window.innerWidth; 17 | var heightWindow = window.innerHeight; 18 | 19 | for (var i = 0; i < qtdeEstrelas; i++) { 20 | estrela += ""; 23 | } 24 | 25 | noite.innerHTML = estrela; 26 | 27 | //meteoros 28 | 29 | var numeroAleatorio = 5000; 30 | 31 | setTimeout(function(){ 32 | carregarMeteoro(); 33 | }, numeroAleatorio); 34 | 35 | function carregarMeteoro(){ 36 | setTimeout(carregarMeteoro, numeroAleatorio); 37 | numeroAleatorio = getRandomArbitrary(5000, 10000); 38 | var meteoro = "
"; 39 | document.getElementsByClassName('chuvaMeteoro')[0].innerHTML = meteoro; 40 | setTimeout(function(){ 41 | document.getElementsByClassName('chuvaMeteoro')[0].innerHTML = ""; 42 | }, 1000); 43 | } 44 | 45 | } 46 | 47 | window.onload = init; -------------------------------------------------------------------------------- /socketIoDemo/server/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Socket-Chat-Example", 3 | "description": "my first socket.io app", 4 | "website": "https://github.com/socketio/chat-example", 5 | "repository": "https://github.com/socketio/chat-example", 6 | "logo": "https://node-js-sample.herokuapp.com/node.svg", 7 | "success_url": "/", 8 | "keywords": [ 9 | "node", 10 | "express", 11 | "socket.io", 12 | "realtime", 13 | "websocket" 14 | ], 15 | "scripts": { 16 | }, 17 | "addons": [ 18 | ], 19 | "env": { 20 | "BUILDPACK_URL": "https://github.com/heroku/heroku-buildpack-nodejs" 21 | } 22 | } -------------------------------------------------------------------------------- /socketIoDemo/server/index.js: -------------------------------------------------------------------------------- 1 | var app = require('express')(); 2 | var http = require('http').Server(app); 3 | var io = require('socket.io')(http); 4 | var port = process.env.PORT || 3200; 5 | 6 | // app.get('/', function(req, res){ 7 | // res.sendFile(__dirname + '/index.html'); 8 | // }); 9 | 10 | let userData = [] 11 | io.on('connection', function(socket){ 12 | socket.on('chat message', function(msg){ 13 | io.emit('chat message', msg) 14 | }); 15 | }); 16 | 17 | http.listen(port, function(){ 18 | console.log('listening on *:' + port); 19 | }); 20 | -------------------------------------------------------------------------------- /socketIoDemo/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket-chat-example", 3 | "version": "0.0.1", 4 | "description": "my first socket.io app", 5 | "dependencies": { 6 | "express": "^4.15.2", 7 | "socket.io": "^1.7.3" 8 | }, 9 | "scripts": { 10 | "start": "node index.js" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ssr-react/app.js: -------------------------------------------------------------------------------- 1 | import express from 'express' 2 | import React from 'react'//引入React以支持JSX的语法 3 | import { renderToString } from 'react-dom/server'//引入renderToString方法 4 | import { StaticRouter } from 'react-router-dom' 5 | import Home from'./src/home' 6 | // 将路由配置对象转换为组件 7 | import { renderRoutes } from 'react-router-config' 8 | // import Router from './src/router'; 9 | import Router from './src/routers' 10 | console.log('router====', Router) 11 | const app = express() 12 | 13 | // 使用express提供的static中间件,中间件会将所有静态文件的路由指向public文件夹 14 | app.use(express.static('public')); 15 | 16 | 17 | // const content = renderToString() 18 | app.get('/', (req, res) => { 19 | const content = renderToString( 20 | // {renderRoutes(router)} 21 | {Router} 22 | ); 23 | res.send(` 24 | 25 | 26 | SSR Demo 27 | 28 | 29 |
30 | ${content} 31 |
32 | 33 | 34 | 35 | `); 36 | }) 37 | 38 | app.listen(3000, () => console.log('Exampleapp listening on port 3000!')) -------------------------------------------------------------------------------- /ssr-react/client/index.js: -------------------------------------------------------------------------------- 1 | // import React from 'react' 2 | // import ReactDom from 'react-dom' 3 | // import Home from '../src/home' 4 | 5 | 6 | // // 使用hydrate在客户端进行二次渲染 7 | // // hydrate 参数1:目标组件,参数2:找到指定元素 8 | // ReactDom.hydrate(
9 | // 10 | //
, document.getElementById('root')) 11 | 12 | 13 | import React from 'react' 14 | import ReactDom from 'react-dom' 15 | import { BrowserRouter } from 'react-router-dom' 16 | import { renderRoutes } from 'react-router-config' 17 | import Router from '../src/router'; 18 | // import Router from '../src/routers' 19 | 20 | // ReactDom.hydrate({renderRoutes(router)}, document.getElementById('root')) 21 | ReactDom.hydrate({ Router }, document.getElementById('root')) -------------------------------------------------------------------------------- /ssr-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ssr-react", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "webpack --config webpack.server.js && webpack --config webpack.client.js && node build/bundle.js", 9 | "dev:client-build": "webpack --config webpack.client.js" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "@babel/core": "^7.22.9", 16 | "@babel/preset-env": "^7.22.9", 17 | "babel-core": "^6.26.3", 18 | "babel-preset-env": "^1.7.0", 19 | "babel-preset-react": "^6.24.1", 20 | "babel-preset-stage-0": "^6.24.1", 21 | "express": "^4.18.2", 22 | "react": "^18.2.0", 23 | "react-dom": "^18.2.0", 24 | "webpack": "^5.88.2", 25 | "webpack-node-externals": "^3.0.0" 26 | }, 27 | "devDependencies": { 28 | "babel-loader": "^7.1.5", 29 | "css-loader": "^6.8.1", 30 | "isomorphic-style-loader": "^5.3.2", 31 | "less-loader": "^11.1.3", 32 | "node-sass": "^9.0.0", 33 | "postcss-loader": "^7.3.3", 34 | "react-router-config": "^5.1.1", 35 | "react-router-dom": "^5.3.4", 36 | "sass-loader": "^13.3.2", 37 | "style-loader": "^3.3.3", 38 | "webpack-cli": "^5.1.4" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ssr-react/src/home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom' 3 | import styles from './index.css'; 4 | const Home = () => { 5 | console.log('styles====', styles.wrapper) 6 | return ( 7 |
8 |
alert('Home click')}> 9 | Home, This is wbh's ssr demo 10 |
11 | 跳转到 text 12 |
13 | ) 14 | } 15 | export default Home -------------------------------------------------------------------------------- /ssr-react/src/index.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | background: orange; 3 | } 4 | 5 | .title { 6 | color: red; 7 | font-size: 26px; 8 | } -------------------------------------------------------------------------------- /ssr-react/src/router.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Route, Redirect, Switch} from 'react-router'; 3 | import Home from './home' 4 | import Text from './text' 5 | 6 | 7 | const routers = [ 8 | { 9 | type: 'route', 10 | path: '/', 11 | component: Home, 12 | exact: true 13 | }, 14 | { 15 | type: 'route', 16 | path: 'text', 17 | component: Text, 18 | exact: true 19 | } 20 | ] 21 | 22 | export default ( { 23 | routers.map((conf, index) => { 24 | const { type, ...otherConf } = conf; 25 | if (type === 'redirect') { 26 | return ; 27 | } else if (type === 'route') { 28 | return ; 29 | } 30 | }).filter(item => item) 31 | }) 32 | -------------------------------------------------------------------------------- /ssr-react/src/routers.js: -------------------------------------------------------------------------------- 1 | import React from 'react' //引入React以支持JSX 2 | import { Route } from 'react-router-dom' //引入路由 3 | import Home from './home' //引入Home组件 4 | import Text from './text' 5 | 6 | export default ( 7 |
8 | 9 | 10 |
11 | ) 12 | -------------------------------------------------------------------------------- /ssr-react/src/text.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Text = () => { 4 | return ( 5 |
6 |
alert('Home click')}> 7 | text, This is wbh's ssr demo 8 |
9 |
10 | ) 11 | } 12 | export default Text -------------------------------------------------------------------------------- /ssr-react/webpack.base.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // 生产环境:开发环境 3 | mode: 'development', 4 | // 配置打包规则 5 | module: { 6 | rules: [ 7 | { //打包规则 8 | test: /\.js?$/, //对所有js文件进行打包 9 | loader: 'babel-loader', //使用babel-loader进行打包 10 | exclude: /node_modules/,//不打包node_modules中的js文件 11 | options: { 12 | presets: ['react', 'stage-0', ['env', { 13 | //loader时额外的打包规则,对react,JSX,ES6进行转换 14 | targets: { 15 | browsers: ['last 2 versions'] //对主流浏览器最近两个版本进行兼容 16 | } 17 | }]] 18 | } 19 | } 20 | ], 21 | }, 22 | } -------------------------------------------------------------------------------- /ssr-react/webpack.client.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const baseConfig = require('./webpack.base') 3 | const { merge } = require('webpack-merge') 4 | 5 | const config = { 6 | // 入口文件 7 | entry: './client/index.js', 8 | // 导出 9 | output: { 10 | // 打包路径:使用path的API进行路径拼接 11 | path: path.join(__dirname, 'public'), 12 | // 打包文件名 13 | filename: 'bundle.js', 14 | }, 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.css?$/, 19 | use: [ 20 | 'style-loader', 21 | 'css-loader', 22 | 'postcss-loader' 23 | ] 24 | } 25 | ] 26 | } 27 | } 28 | 29 | module.exports = merge(baseConfig, config) -------------------------------------------------------------------------------- /ssr-react/webpack.server.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const baseConfig = require('./webpack.base') 3 | const { merge } = require('webpack-merge') 4 | const nodeExternals = require('webpack-node-externals') 5 | 6 | const config = { 7 | // 代码运行环境:node 8 | target: 'node', 9 | // 入口文件 10 | entry: './app.js', 11 | // 导出 12 | output: { 13 | // 打包路径:使用path的API进行路径拼接 14 | path: path.join(__dirname, 'build'), 15 | // 打包文件名 16 | filename: 'bundle.js', 17 | }, 18 | externals: [nodeExternals()], 19 | module: { 20 | rules: [ 21 | { 22 | test: /\.css?$/, 23 | use: [ 24 | 'isomorphic-style-loader', 25 | 'css-loader', 26 | 'postcss-loader',] 27 | } 28 | ] 29 | } 30 | } 31 | 32 | module.exports = merge(baseConfig, config) 33 | -------------------------------------------------------------------------------- /swiper/sdk/plugins/autoPlay.ts: -------------------------------------------------------------------------------- 1 | import Swiper from ".."; 2 | 3 | interface IAutoPlayPluginOptions { 4 | delay?: number 5 | disableOnInteraction: boolean 6 | }; 7 | class AutoPlayPlugin { 8 | options: IAutoPlayPluginOptions 9 | timeout: number | null; 10 | swiper: Swiper | null; 11 | constructor(options: IAutoPlayPluginOptions = { 12 | delay: 3000, 13 | disableOnInteraction: false 14 | }) { 15 | this.options = { 16 | delay: options.delay || 3000, 17 | ...options 18 | }; 19 | this.timeout = null; 20 | this.swiper = null; 21 | } 22 | install(swiper: Swiper) { 23 | this.swiper = swiper; 24 | swiper.autoplay = { 25 | start: this.start.bind(this), 26 | stop: this.stop.bind(this) 27 | }; 28 | // 用户交互时停止自动播放 29 | if (this.options.disableOnInteraction) { 30 | ['mousedown', 'touchstart'].forEach(eventName => { 31 | swiper.container.addEventListener(eventName, () => { 32 | this.stop(); 33 | }); 34 | }); 35 | } 36 | } 37 | start() { 38 | if (!this.swiper) return; 39 | this.stop(); 40 | this.timeout = setTimeout(() => { 41 | if (this.swiper!.currentIndex < this.swiper!.slides.length - 1) { 42 | this.swiper!.currentIndex++; 43 | } else { 44 | this.swiper!.currentIndex = 0; 45 | } 46 | this.swiper!.slideTo(this.swiper!.currentIndex); 47 | this.start(); 48 | }, this.options.delay); 49 | } 50 | stop() { 51 | if (this.timeout !== null) { 52 | clearTimeout(this.timeout); 53 | this.timeout = null; 54 | } 55 | } 56 | 57 | } 58 | 59 | export default AutoPlayPlugin; -------------------------------------------------------------------------------- /visualization-selection/utils.js: -------------------------------------------------------------------------------- 1 | function throttle(func, wait = 100) { 2 | let timeout = null; 3 | let elapsed; 4 | let lastRunTime = Date.now(); // 上次运行时间 5 | return function none(content, ...args) { 6 | const _this = content; 7 | 8 | if (typeof timeout === 'number') { 9 | window.clearTimeout(timeout); 10 | } 11 | 12 | elapsed = Date.now() - lastRunTime; 13 | 14 | function later() { 15 | lastRunTime = Date.now(); 16 | timeout = null; 17 | console.log('content---', _this) 18 | func.call(_this, _this); 19 | } 20 | 21 | if (elapsed > wait) { 22 | later(); 23 | } else { 24 | timeout = window.setTimeout(later, wait - elapsed); 25 | } 26 | }; 27 | } -------------------------------------------------------------------------------- /vue+jquery数学公式编辑/README.md: -------------------------------------------------------------------------------- 1 | 未知数: 2 | -------------------------------------------------------------------------------- /vue+jquery数学公式编辑/js/data-tool.js: -------------------------------------------------------------------------------- 1 | function deepCopy(obj) { 2 | // 深度复制数组 3 | if (Object.prototype.toString.call(obj) === "[object Array]") { 4 | const object = []; 5 | for (let i = 0; i < obj.length; i++) { 6 | object.push(deepCopy(obj[i])) 7 | } 8 | return object 9 | } 10 | // 深度复制对象 11 | if (Object.prototype.toString.call(obj) === "[object Object]") { 12 | const object = {}; 13 | for (let p in obj) { 14 | object[p] = obj[p] 15 | } 16 | return object 17 | } 18 | } 19 | 20 | function treeToArray(treeObj) { 21 | var queen = []; 22 | var out = []; 23 | queen = queen.concat(treeObj); 24 | while(queen.length) { 25 | var first = queen.shift(); 26 | if (first.components) { 27 | queen = queen.concat(first.components) 28 | delete first['components']; 29 | } 30 | 31 | out.push(first); 32 | } 33 | return out; 34 | } 35 | 36 | function dataToTree(data, itemId, parentId) { 37 | // 删除 所有 children,以防止多次调用 38 | data.forEach(function(item) { 39 | delete item.components; 40 | }); 41 | // 将数据存储为 以 id 为 KEY 的 map 索引数据列 42 | var map = {}; 43 | data.forEach(function(item) { 44 | map[item[itemId]] = item; 45 | }); 46 | 47 | var val = []; 48 | data.forEach(function(item) { 49 | // 以当前遍历项,的pid,去map对象中找到索引的id 50 | var parent = map[item[parentId]]; 51 | // 好绕啊,如果找到索引,那么说明此项不在顶级当中,那么需要把此项添加到,他对应的父级中 52 | if (parent) { 53 | (parent.components || (parent.components = [])).push(item); 54 | } else { 55 | //如果没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中,作为顶级 56 | val.push(item); 57 | } 58 | }); 59 | return val; 60 | } 61 | -------------------------------------------------------------------------------- /word-cloud/README.md: -------------------------------------------------------------------------------- 1 | list 格式1: [ 显示内容, 内容大小,内容颜色] 2 | 3 | 4 | 5 | list: [ 6 | ['Google', 15, 'red'], 7 | ['JD', 12], 8 | ['GoogleA', 10], 9 | ['Alibaba', 7], 10 | ['Baidu', 6], 11 | ['NetEase', 4], 12 | ['Youku', 4], 13 | ['Meituan', 3], 14 | ['Douban', 3], 15 | ] 16 | 17 | 18 | list 格式2: 19 | 20 | list: [ 21 | { 22 | word: 'Google', 23 | weight: 15, 24 | color: 'red', 25 | }, 26 | { 27 | word: 'JD', 28 | weight: 12, 29 | }, 30 | { 31 | word: 'GoogleA', 32 | weight: 10, 33 | }, 34 | { 35 | word: 'Tencent', 36 | weight: 9, 37 | }, 38 | ], 39 | -------------------------------------------------------------------------------- /word-cloud/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /word-cloud/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ item.word }} 5 | 6 | 7 | -------------------------------------------------------------------------------- /word-cloud/index.wxss: -------------------------------------------------------------------------------- 1 | /* components/word-cloud/index.wxss */ 2 | 3 | .wc-canvas { 4 | display: none; 5 | position: absolute; 6 | z-index: -1; 7 | } 8 | .wc-main { 9 | position: relative; 10 | } 11 | .wc-item { 12 | white-space: nowrap; 13 | position: absolute; 14 | display: block; 15 | transform-origin: 50% 40%; 16 | } 17 | -------------------------------------------------------------------------------- /wx-set-appid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wx-config-npm", 3 | "version": "1.0.0", 4 | "description": "", 5 | "bin": { 6 | "set-wx": "./wx-config.js" 7 | }, 8 | "main": "wx-config.js", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /wxchart/.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /wxchart/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /wxchart/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /wxchart/.idea/wxchart.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /wxchart/drawutil.js: -------------------------------------------------------------------------------- 1 | class DrawUtil{ 2 | constructor(ctx) { 3 | try { 4 | if (!(ctx instanceof CanvasRenderingContext2D)) throw '画布实例对象错误!' 5 | this.ctx = ctx 6 | } catch (e) { 7 | console.error(e) 8 | } 9 | } 10 | drawLineX(x1,x2, top=0, left=0) { 11 | let ctx = this.ctx 12 | ctx.beginPath(); 13 | ctx.moveTo(x1 + left, top); 14 | ctx.lineTo(x2 + left, top); 15 | ctx.closePath(); 16 | ctx.stroke(); 17 | } 18 | 19 | drawLineY(y1,y2, top=0, left=0) { 20 | let ctx = this.ctx 21 | ctx.beginPath(); 22 | ctx.moveTo(left, y1 + top); 23 | ctx.lineTo(left, y2 + top); 24 | ctx.closePath(); 25 | ctx.stroke(); 26 | } 27 | } -------------------------------------------------------------------------------- /wxchart/scalelinear.js: -------------------------------------------------------------------------------- 1 | class MyScaleLinear { 2 | constructor() { 3 | this.domainVal = [] 4 | this.rangeVal = [] 5 | } 6 | domain(arr) { 7 | try { 8 | if (!Array.isArray(arr)) throw 'domain 参数不是一个数组!'; 9 | if (arr.length !== 2) throw 'domain 数组长度不为2'; 10 | this.domainVal = [...arr]; 11 | } 12 | catch (e) { 13 | console.error(e) 14 | } 15 | return this; 16 | } 17 | range(arr) { 18 | try { 19 | if (!Array.isArray(arr)) throw 'domain 参数不是一个数组!'; 20 | if (arr.length !== 2) throw 'domain 数组长度不为2'; 21 | this.rangeVal = [...arr]; 22 | } 23 | catch (e) { 24 | console.error(e) 25 | } 26 | return this.findRange.bind(this); 27 | } 28 | 29 | findRange(val){ 30 | let result = (val - this.domainVal[0]) / (this.domainVal[1] - this.domainVal[0]) * (this.rangeVal[1] - this.rangeVal[0]) + this.rangeVal[0]; 31 | return result 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /wxchart/scaleordinal.js: -------------------------------------------------------------------------------- 1 | class MyScaleOrdinal { 2 | constructor() { 3 | this.domainVal = [] 4 | this.rangeVal = [] 5 | } 6 | domain(arr) { 7 | try { 8 | if (!Array.isArray(arr)) throw 'domain 参数不是一个数组。' 9 | this.domainVal = [...arr] 10 | } catch (e) { 11 | console.error(e) 12 | } 13 | return this 14 | } 15 | range(arr) { 16 | try { 17 | if (!Array.isArray(arr)) throw 'range 参数不是一个数组。' 18 | this.rangeVal = [...arr] 19 | } catch (e) { 20 | console.error(e) 21 | } 22 | return this.findRange.bind(this); 23 | } 24 | findRange(val){ 25 | let index = this.domainVal.findIndex((item) => item === val); 26 | let rlen = this.rangeVal.length 27 | if (rlen > index) return this.rangeVal[index] 28 | return this.rangeVal[index % rlen]; 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /wxchart/scalepie.js: -------------------------------------------------------------------------------- 1 | class ScalePie{ 2 | constructor() { 3 | this.arcData = [] 4 | this.hasValueFunc = false 5 | this.valueFunc = null 6 | } 7 | value(fn) { 8 | this.hasValueFunc = true; 9 | this.valueFunc = fn 10 | return this 11 | } 12 | getArcs(arr) { 13 | try { 14 | if (!Array.isArray(arr)) throw 'getArcs 参数为非数组' 15 | this.arcData = [...arr] 16 | this.arcData.sort((a, b) =>{ 17 | if (this.hasValueFunc) return this.valueFunc(b) - this.valueFunc(a) 18 | return b - a 19 | }) 20 | let totals = this.arcData.reduce((total, num) => { 21 | if ( this.hasValueFunc) return total + this.valueFunc(num) 22 | return total + num 23 | },0) 24 | let result = [] 25 | let resObj = {} 26 | let resValue = 0 27 | let lastAngle = 0 28 | let currentAngle = 0 29 | this.arcData.forEach((num)=>{ 30 | resValue = num 31 | if ( this.hasValueFunc) resValue = this.valueFunc(num) 32 | currentAngle = lastAngle + resValue / totals * Math.PI * 2 33 | resObj = { 34 | data: num, 35 | value: resValue, 36 | startAngle: lastAngle, 37 | endAngle: currentAngle 38 | } 39 | result.push(resObj) 40 | lastAngle = currentAngle 41 | }) 42 | return result 43 | } catch (e) { 44 | console.error(e) 45 | } 46 | return [] 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /zotero/LXGWWenKai-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/zotero/LXGWWenKai-Regular.ttf -------------------------------------------------------------------------------- /zotero/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "USE_MODELSCOPE": "0", 3 | "PDF2ZH_LANG_FROM": "English", 4 | "PDF2ZH_LANG_TO": "Simplified Chinese", 5 | "NOTO_FONT_PATH": "./LXGWWenKai-Regular.ttf", 6 | "translators": [ 7 | { 8 | "name": "deepseek", 9 | "envs": { 10 | "DEEPSEEK_API_KEY": "sk-xxxxxxx", 11 | "DEEPSEEK_MODEL": "deepseek-chat" 12 | } 13 | }, 14 | { 15 | "name": "zhipu", 16 | "envs": { 17 | "ZHIPU_API_KEY": "95e618cbd2de430c8222d550755e5bc1.tabMBYmowR3Ug4l0", 18 | "ZHIPU_MODEL": "glm-4-flash" 19 | } 20 | }, 21 | { 22 | "name": "openailiked", 23 | "envs": { 24 | "OPENAILIKED_BASE_URL": "https://ark.cn-beijing.volces.com/api/v3", 25 | "OPENAILIKED_API_KEY": "xxxxx", 26 | "OPENAILIKED_MODEL": "ep-xxxx-xxxxx" 27 | } 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /zotero/zotero-pdf-2-zh.xpi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WtecHtec/WorkNotes/0c32dfde62922275f0784d9331eee8e4bdcf2dc7/zotero/zotero-pdf-2-zh.xpi -------------------------------------------------------------------------------- /设计模式/创建模式/abstractFactory.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 抽象工厂 3 | * 通过抽象工厂接口,创建不同产品的实例类 4 | */ 5 | 6 | /** 7 | * 抽象产品类 8 | */ 9 | class Car { 10 | constructor(name) { 11 | this.name = name 12 | } 13 | getName() { 14 | console.log('name==:', this.name) 15 | } 16 | } 17 | 18 | class LowCar extends Car { 19 | constructor(name) { 20 | super(name) 21 | } 22 | } 23 | 24 | class IntermediateCar extends Car { 25 | constructor(name) { 26 | super(name) 27 | } 28 | } 29 | 30 | 31 | 32 | class HighCar extends Car { 33 | constructor(name) { 34 | super(name) 35 | } 36 | } 37 | 38 | /** 39 | * 抽象工厂类 40 | */ 41 | class AbstractFactory { 42 | createLow() {} 43 | createIntermediate() {} 44 | createHigh() {} 45 | } 46 | 47 | 48 | /** 49 | * 工厂类 50 | */ 51 | class CarFactory extends AbstractFactory { 52 | createLow() { 53 | return new LowCar('低级') 54 | } 55 | createIntermediate() { 56 | return new IntermediateCar('中级') 57 | } 58 | createHigh() { 59 | return new HighCar('高级') 60 | } 61 | } 62 | 63 | const carFactory = new CarFactory() 64 | carFactory.createLow().getName() 65 | carFactory.createIntermediate().getName() 66 | carFactory.createHigh().getName() -------------------------------------------------------------------------------- /设计模式/创建模式/prototype.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 原型模式 3 | * 实例化一个对象耗时,相比之下复制一个原型对象比较快 4 | */ 5 | 6 | class EnemyPlane { 7 | constructor(x = 0) { 8 | this.x = x 9 | } 10 | fly() { 11 | console.log('flying') 12 | } 13 | } 14 | 15 | function deep(obj) { 16 | return Object.assign({}, obj) 17 | } 18 | 19 | class EnemyPlaneFactory { 20 | static getEnemyPlane() { 21 | // 单例模式 22 | if (!this.instance) this.instance = new EnemyPlane() 23 | // 原型链拷贝 24 | return this.instance 25 | } 26 | } 27 | 28 | console.log(EnemyPlaneFactory) 29 | console.time() 30 | for (let i = 0; i < 10; i++) { 31 | const ep = new EnemyPlane() 32 | // const ep = EnemyPlaneFactory.getEnemyPlane() 33 | } 34 | console.timeEnd() -------------------------------------------------------------------------------- /设计模式/创建模式/simpleFactory.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 简单工厂 3 | * 根据类型创建不同的实例 4 | * 可以创建一个工厂创建接口,继承这个接口,代表一个工厂类 5 | */ 6 | 7 | /** 抽象类 */ 8 | class Enemy { 9 | constructor(x, y) { 10 | this.x = x 11 | this.y = y 12 | } 13 | show() { 14 | console.log(' Enemy show') 15 | } 16 | } 17 | 18 | class Tank extends Enemy { 19 | constructor(x, y) { 20 | super(x, y) 21 | } 22 | show() { 23 | console.log(' Tank show') 24 | } 25 | } 26 | 27 | 28 | class Airplane extends Enemy { 29 | constructor(x, y) { 30 | super(x, y) 31 | } 32 | show() { 33 | console.log(' Airplane show') 34 | } 35 | } 36 | 37 | /** 38 | * 简单工厂类 39 | */ 40 | class SimpleFactory { 41 | constructor() { 42 | 43 | } 44 | create(type) { 45 | switch (type) { 46 | case 'tank': 47 | return new Tank() 48 | break 49 | case 'airplane': 50 | return new Airplane() 51 | break 52 | default: 53 | console.log('empty') 54 | } 55 | } 56 | } 57 | 58 | const simpleFactory = new SimpleFactory() 59 | simpleFactory.create('tank').show() 60 | simpleFactory.create('airplane').show() 61 | 62 | 63 | /** 64 | * 工厂接口 65 | */ 66 | class FactoryInteface { 67 | create(type) { } 68 | } 69 | 70 | /** 71 | * tank 工厂类 72 | */ 73 | class TankFactory extends FactoryInteface { 74 | create(type) { 75 | switch (type) { 76 | case 'tank': 77 | return new Tank() 78 | break 79 | default: 80 | console.log('empty') 81 | } 82 | } 83 | } 84 | 85 | 86 | 87 | const tankFactory = new TankFactory() 88 | tankFactory.create('tank').show() -------------------------------------------------------------------------------- /设计模式/创建模式/singleton.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 单例模式 4 | * 一个类仅有一个实例 5 | * 全局只有一个实例类 6 | */ 7 | class Sun { 8 | // #instance 9 | constructor() { 10 | console.log('constructor', this.instance) 11 | } 12 | 13 | static getInstance() { 14 | console.log('getInstance') 15 | if (!this.instance) this.instance = new Sun() 16 | return this.instance 17 | } 18 | 19 | run() { 20 | console.log('run') 21 | } 22 | } 23 | 24 | // const sun = new Sun() 25 | Sun.getInstance() 26 | const instance = Sun.getInstance() 27 | 28 | console.log(instance) -------------------------------------------------------------------------------- /设计模式/结构模式/adapter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 适配模式 3 | * 当一个对象或类的接口不能匹配用户所期待的接口时,适配器就充当中间转换的角色,以达到兼容用户接口的目的,同时适配器也实现了客户端与接口的解耦,提高了组件的可复用性。 4 | * 例子:电视机 两孔插座适配三孔插座,需要一个转接头 5 | */ 6 | 7 | // 两孔插座抽象类 8 | class DualPin { 9 | electrify(l, n) { 10 | console.log('两孔====', l, n) 11 | } 12 | } 13 | 14 | class TriplePin { 15 | electrify(l, n, e) { 16 | console.log('三孔====', l, n, e) 17 | } 18 | } 19 | 20 | class TV extends DualPin { 21 | electrify(l, n) { 22 | console.log('两孔====', l, n) 23 | console.log('开机') 24 | } 25 | } 26 | 27 | class Adapter extends TriplePin { 28 | constructor(inDualPin) { 29 | super() 30 | this.dualPin = inDualPin 31 | } 32 | electrify(l, n, e) { 33 | console.log('三孔====', l, n, e) 34 | this.dualPin.electrify(l, n) 35 | } 36 | } 37 | 38 | const tv = new TV() 39 | const adapter = new Adapter(tv) 40 | adapter.electrify(0,1,2) -------------------------------------------------------------------------------- /设计模式/结构模式/bridge.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 桥接模式 3 | * 抽象与实现分离,使二者可以各自单独变化而不受对方约束,使用时再将它们组合起来,就像架设桥梁一样连接它们的功能 4 | * 例如:使用尺子绘制不同颜色的形状 5 | */ 6 | 7 | // 尺子接口 8 | class Ruler { 9 | regularize() { } 10 | } 11 | 12 | class SquareRuler extends Ruler { 13 | constructor() { super() } 14 | regularize() { 15 | console.log('正方形') 16 | } 17 | } 18 | 19 | class TriangleRuler extends Ruler { 20 | constructor() { super() } 21 | regularize() { 22 | console.log('三角形') 23 | } 24 | } 25 | 26 | class Pen { 27 | constructor(inRule) { 28 | this.rule = inRule 29 | } 30 | draw() {} 31 | } 32 | 33 | 34 | class WhitePen extends Pen { 35 | constructor(inRule) { 36 | super(inRule) 37 | } 38 | draw() { 39 | console.log('白色', ) 40 | this.rule.regularize() 41 | } 42 | } 43 | 44 | 45 | class BlackPen extends Pen { 46 | constructor(inRule) { 47 | super(inRule) 48 | } 49 | draw() { 50 | console.log('黑色') 51 | this.rule.regularize() 52 | } 53 | } 54 | 55 | 56 | new WhitePen(new TriangleRuler()).draw() 57 | -------------------------------------------------------------------------------- /设计模式/结构模式/builder.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 建造模式 3 | * 一步一步创建完整的产品类实例 4 | * 例如: 创建一个汽车类,需要有 ’车身‘, ’喷漆‘ 5 | */ 6 | 7 | /** 产品类 */ 8 | class Car { 9 | constructor() {} 10 | 11 | setColor() { 12 | console.log('喷漆') 13 | } 14 | 15 | setBody() { 16 | console.log('车身') 17 | } 18 | } 19 | 20 | /** 建造类 */ 21 | class Builder { 22 | createColor(){} 23 | createBody(){} 24 | } 25 | 26 | class ConcreteBuilder extends Builder { 27 | constructor(inCar) { 28 | super() 29 | this.car = inCar || new Car() 30 | } 31 | createColor(){ 32 | this.car.setColor() 33 | } 34 | createBody(){ 35 | this.car.setBody() 36 | } 37 | } 38 | 39 | 40 | const concrete = new ConcreteBuilder() 41 | concrete.createBody() 42 | concrete.createColor() 43 | -------------------------------------------------------------------------------- /设计模式/结构模式/composite.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 组合模式 3 | * 对象组合成树状结构, 并且能像使用独立对象一样使用它们。 4 | * 例如: 文件系统 5 | */ 6 | 7 | // 节点抽象基类 8 | class Node { 9 | constructor(name) { 10 | this.name = name 11 | } 12 | addChild(node) { 13 | console.log('添加子节点') 14 | } 15 | } 16 | 17 | // 文件夹 18 | class Folder extends Node { 19 | constructor(){ 20 | super('Folder') 21 | this.nodeList = [] 22 | } 23 | addChild(node) { 24 | console.log('添加子节点===:', node) 25 | this.nodeList.push(node) 26 | } 27 | } 28 | 29 | // 文件 30 | class File extends Node { 31 | constructor(){ 32 | super('File') 33 | } 34 | addChild(node) { 35 | console.log('不能添加子节点') 36 | } 37 | } 38 | 39 | const root = new Folder() 40 | const file = new File() 41 | root.addChild(file) 42 | 43 | 44 | -------------------------------------------------------------------------------- /设计模式/结构模式/decorator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 装饰模式 3 | * 装饰器非常类似于“继承”,它们都是为了增强原始对象的功能,区别在于方式的不同, 4 | * 后者是在编译时(compile-time)静态地通过对原始类的继承完成, 5 | * 而前者则是在程序运行时(run-time)通过对原始对象动态地“包装”完成,是对类实例(对象)“装饰”的结果。 6 | */ 7 | 8 | // 抽象基类 9 | class Showable { 10 | show() {} 11 | } 12 | 13 | class Girl extends Showable { 14 | show() { 15 | console.log('面部---') 16 | } 17 | } 18 | 19 | // 装饰抽象类 20 | class Decorator extends Showable { 21 | constructor(showable) { 22 | super() 23 | this.showable = showable 24 | } 25 | show() { 26 | this.showable.show() 27 | } 28 | } 29 | 30 | // 口红 31 | class FoundationMakeup extends Decorator { 32 | constructor(showable) { 33 | super(showable) 34 | this.showable = showable 35 | } 36 | show() { 37 | console.log('口红---') 38 | this.showable.show() 39 | } 40 | } 41 | 42 | // 粉底 43 | class Lipstick extends Decorator { 44 | constructor(showable) { 45 | super(showable) 46 | this.showable = showable 47 | } 48 | show() { 49 | console.log('粉底---') 50 | this.showable.show() 51 | } 52 | } 53 | const decorator = new Lipstick(new FoundationMakeup(new Girl())) 54 | decorator.show() -------------------------------------------------------------------------------- /设计模式/结构模式/facade.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 外观模式 3 | * 通过封装多个子系统,提供外部方法实现需求操作 4 | * 例如: 饭店,对于客户就是为了吃饭,饭店做饭,买菜等操作,客户是不关心的 5 | */ 6 | 7 | // 服务员 8 | class Waiter { 9 | order() { 10 | console.log('招待、下单') 11 | } 12 | 13 | serve() { 14 | console.log('上菜') 15 | } 16 | } 17 | 18 | // 厨师 19 | class Chef { 20 | cook() { 21 | console.log('厨师下厨') 22 | } 23 | } 24 | 25 | // 清洁工 26 | class Cleaner { 27 | clean() { 28 | console.log('清洁') 29 | } 30 | } 31 | 32 | 33 | class Facade { 34 | constructor() { 35 | this.waiter = new Waiter() 36 | this.chef = new Chef() 37 | this.cleaner = new Cleaner() 38 | } 39 | 40 | order() { 41 | this.waiter.order() 42 | this.chef.cook() 43 | this.waiter.serve() 44 | this.cleaner.clean() 45 | } 46 | } 47 | 48 | 49 | const facade = new Facade() 50 | facade.order() 51 | 52 | 53 | -------------------------------------------------------------------------------- /设计模式/结构模式/flyweight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 享元模式 3 | * 缓存多个实例,使用时直接从缓存中获取 4 | * 例如:游戏渲染图片, 5 | */ 6 | 7 | class Drawable { 8 | draw(x, y) { console.log(`位置${x},${y} 渲染图片`) } 9 | } 10 | 11 | class Grass extends Drawable { 12 | constructor() { 13 | super() 14 | this.image = '草地' 15 | } 16 | draw(x, y) { console.log(`位置${x},${y} 渲染${this.image}`) } 17 | } 18 | 19 | class Stone extends Drawable { 20 | constructor() { 21 | super() 22 | this.image = '道路' 23 | } 24 | draw(x, y) { console.log(`位置${x},${y} 渲染${this.image}`) } 25 | } 26 | 27 | class House extends Drawable { 28 | constructor() { 29 | super() 30 | this.image = '房屋' 31 | } 32 | draw(x, y) { console.log(`位置${x},${y} 渲染${this.image}`) } 33 | } 34 | 35 | class TileFactory { 36 | constructor() { 37 | this.cache = {} 38 | } 39 | getDrawable(name) { 40 | if (!this.cache[name]) { 41 | switch (name) { 42 | case '草地': 43 | this.cache[name] = new Grass() 44 | break 45 | case '道路': 46 | this.cache[name] = new Stone() 47 | break 48 | case '房屋': 49 | this.cache[name] = new House() 50 | break 51 | default: 52 | break 53 | } 54 | } 55 | return this.cache[name] 56 | } 57 | } 58 | 59 | const tileFactory = new TileFactory() 60 | tileFactory.getDrawable('草地').draw(10, 20) -------------------------------------------------------------------------------- /设计模式/结构模式/proxy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 代理模式 3 | * 从某种意义上讲,这是代理模式区别于装饰器模式的一种体现。虽然二者的理念与实现有点类似, 4 | * 但装饰器模式往往更加关注为其他对象增加功能,让客户端更加灵活地进行组件搭配; 5 | * 而代理模式更强调的则是一种对访问的管控,甚至是将被代理对象完全封装而隐藏起来,使其对客户端完全透明。 6 | * 7 | * 例子:拨号上网 8 | */ 9 | 10 | // 上网接口 11 | class Internet { 12 | httpAccess(url) { console.log(url)} 13 | } 14 | 15 | // 拨号 16 | class Modem extends Internet { 17 | constructor() { 18 | super() 19 | console.log('拨号上网') 20 | } 21 | httpAccess(url) { 22 | console.log(`访问:${url}`) 23 | } 24 | } 25 | 26 | // 代理 27 | class RouterProxy extends Internet { 28 | constructor() { 29 | super() 30 | this.modem = new Modem() 31 | this.blackList = ['php'] 32 | } 33 | httpAccess(url) { 34 | if (this.blackList.includes(url)) { 35 | console.log(`禁止访问:${url}`) 36 | return 37 | } 38 | this.modem.httpAccess(url) 39 | } 40 | } 41 | 42 | const routerProxy = new RouterProxy() 43 | 44 | routerProxy.httpAccess('php') 45 | routerProxy.httpAccess('juejin') 46 | -------------------------------------------------------------------------------- /设计模式/行为模式/command.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 命令模式(map 记录操作,根据 key 作为寻址) 3 | * 4 | * “将指令信息封装成一个对象,并将此对象作为参数发送给接收方去执行, 5 | * 以使命令的请求方与执行方解耦,双方只通过传递各种命令过象来完成任务” 6 | * 7 | * 例如:操作电视剧 8 | */ 9 | 10 | class Command { 11 | exe() { } 12 | unexe() { } 13 | } 14 | 15 | class TV { 16 | constructor() { } 17 | on() { 18 | console.log('开机') 19 | } 20 | off() { 21 | console.log('关机') 22 | } 23 | 24 | volumeUp() { 25 | console.log('音量+') 26 | } 27 | 28 | volumeDown() { 29 | console.log('音量-') 30 | } 31 | } 32 | 33 | class TVOnCommand extends Command { 34 | constructor(tv) { 35 | super() 36 | this.tv = tv 37 | } 38 | exe() { this.tv.on() } 39 | unexe() { this.tv.off() } 40 | } 41 | 42 | class TVOffCommand extends Command { 43 | constructor(tv) { 44 | super() 45 | this.tv = tv 46 | } 47 | exe() { this.tv.off() } 48 | unexe() { this.tv.on() } 49 | } 50 | 51 | 52 | class TVVolumeUpCommand extends Command { 53 | constructor(tv) { 54 | super() 55 | this.tv = tv 56 | } 57 | exe() { this.tv.volumeUp() } 58 | unexe() { this.tv.volumeDown() } 59 | } 60 | 61 | class TVVolumeDownCommand extends Command { 62 | constructor(tv) { 63 | super() 64 | this.tv = tv 65 | } 66 | exe() { this.tv.volumeDown() } 67 | unexe() { this.tv.volumeUp() } 68 | } 69 | 70 | class Keyboard { 71 | constructor() { 72 | this.keyCommands = {} 73 | } 74 | bindKeyCommand(key, commands) { 75 | this.keyCommands[key] = [...commands] 76 | } 77 | onKeyPressed(key) { 78 | this.keyCommands[key].forEach(item => { 79 | item.exe() 80 | }); 81 | } 82 | } 83 | 84 | const keyboard = new Keyboard() 85 | const tv = new TV() 86 | keyboard.bindKeyCommand('f1', [ 87 | new TVOnCommand(tv), 88 | new TVVolumeUpCommand(tv), 89 | new TVVolumeUpCommand(tv), 90 | new TVVolumeUpCommand(tv), 91 | new TVVolumeUpCommand(tv), 92 | ]) 93 | 94 | keyboard.onKeyPressed('f1') -------------------------------------------------------------------------------- /设计模式/行为模式/iterator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 迭代模式 3 | * “提供了一种机制来按顺序访问集合中的各元素,而不需要知道集合内部的构造。” 4 | * 例如: 一页一页的翻书 5 | */ 6 | 7 | // 迭代接口 8 | class iterator { 9 | next() { console.log('下一页') } 10 | hasNext() { console.log('结束?') } 11 | } 12 | 13 | class Books extends iterator { 14 | constructor() { 15 | super() 16 | this.pages = [] 17 | this.size = 10 18 | this.index = 0 19 | } 20 | append() { 21 | if (this.pages.length >= this.size) return 22 | this.pages.push(Math.random()) 23 | } 24 | next() { 25 | console.log(`第${this.pages[this.index]}页`) 26 | this.index += 1 27 | } 28 | hasNext() { 29 | 30 | if (this.index >= this.pages.length) { 31 | console.log('结束') 32 | return true 33 | } 34 | return false 35 | } 36 | } 37 | 38 | const book = new Books() 39 | book.append() 40 | book.append() 41 | book.append() 42 | book.append() 43 | while (!book.hasNext()) { 44 | book.next() 45 | } -------------------------------------------------------------------------------- /设计模式/行为模式/mediator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 中介模式 3 | * “为对象构架出一个互动平台,通过减少对象间的依赖程度以达到解耦的目的” 4 | * 例如: 聊天室 5 | */ 6 | 7 | // 中介(聊天平台) 8 | class ChatRoom { 9 | constructor() { 10 | this.userList = [] 11 | } 12 | register(user) { 13 | this.userList.push(user) 14 | console.log(`${user.getName()}加入`) 15 | } 16 | 17 | sendMSG(formUser, msg) { 18 | this.userList.forEach(item => { 19 | item.listen(formUser, msg) 20 | }) 21 | } 22 | } 23 | class User { 24 | constructor(name) { 25 | this.name = name 26 | this.chatRoom = null 27 | } 28 | getName() { 29 | return this.name 30 | } 31 | login(chatRoom) { 32 | this.chatRoom = chatRoom 33 | this.chatRoom.register(this) 34 | } 35 | talk(msg) { 36 | this.chatRoom.sendMSG(this, msg) 37 | } 38 | 39 | listen(formUser, msg) { 40 | console.log(`${this.getName()}收到:${formUser.getName()} 发送信息(${msg})`) 41 | } 42 | } 43 | 44 | const chatRoom = new ChatRoom() 45 | 46 | const u1 = new User('u1') 47 | const u2 = new User('u2') 48 | const u3 = new User('u3') 49 | 50 | u1.login(chatRoom) 51 | u2.login(chatRoom) 52 | 53 | u1.talk('hello') -------------------------------------------------------------------------------- /设计模式/行为模式/memento.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 备忘录模式 3 | * 缓存机制,返回上一步等操作使用 4 | * 例子:记笔记 5 | */ 6 | 7 | // 单个数据历史类 8 | class History { 9 | constructor(body) { 10 | this.body = body 11 | } 12 | getBody() { 13 | return this.body 14 | } 15 | } 16 | 17 | // 笔记类 18 | class Doc { 19 | constructor() { 20 | this.title = '' 21 | this.body = '' 22 | } 23 | setTitle(title) { 24 | this.title = title 25 | } 26 | getTitle() { 27 | return this.title 28 | } 29 | setBody(body) { 30 | this.body = body 31 | } 32 | getBody() { 33 | return this.body 34 | } 35 | 36 | createHistory() { 37 | return new History(this.body) 38 | } 39 | restoreHistory(history) { 40 | this.body = history.getBody() 41 | } 42 | } 43 | 44 | class Editor { 45 | constructor(doc) { 46 | this.doc = doc 47 | this.historys = [] // 历史记录 48 | this.hisIndex = 0 // 历史记录位置 49 | } 50 | 51 | // 保存记录 52 | backup() { 53 | this.historys.push(this.doc.createHistory()) 54 | this.hisIndex ++ 55 | } 56 | 57 | show() { 58 | console.log('显示:',this.doc.getBody()) 59 | } 60 | 61 | write(body) { 62 | this.doc.setBody(body) 63 | this.backup() 64 | this.show() 65 | } 66 | 67 | undo() { 68 | if (this.hisIndex === 0) { 69 | console.log('end') 70 | return 71 | } 72 | this.hisIndex -- 73 | const history = this.historys[this.hisIndex] 74 | this.doc.restoreHistory(history) 75 | this.show() 76 | } 77 | 78 | } 79 | 80 | const editor = new Editor(new Doc()) 81 | editor.write('测试') 82 | editor.write('测试1') 83 | 84 | editor.undo() 85 | editor.undo() 86 | editor.undo() 87 | // editor.show() -------------------------------------------------------------------------------- /设计模式/行为模式/observer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 观察者模式 3 | * 4 | * 针对被观察对象与观察者对象之间一对多的依赖关系建立起一种行为自动触发机制,当被观察对象状态发生变化时主动对外发起广播,以通知所有观察者做出响应。 5 | * 6 | */ 7 | 8 | 9 | class Shop { 10 | 11 | constructor() { 12 | this.product = "无商品"; 13 | this.buyers = [] 14 | } 15 | //商店出货 16 | getProduct() { 17 | return this.product; 18 | } 19 | //商店进货 20 | setProduct(product) { 21 | this.product = product; 22 | // 通知 23 | this.notifyBuyers() 24 | } 25 | 26 | 27 | // 注册买家到预订清单中 28 | register(buyer) { 29 | this.buyers.push(buyer); 30 | } 31 | 32 | // 通知所有注册买家 33 | notifyBuyers() { 34 | this.buyers.forEach(b => b.inform(this.getProduct())); 35 | } 36 | } 37 | 38 | 39 | class Buyer { 40 | 41 | constructor(name) { 42 | this.name = name; 43 | } 44 | 45 | inform(product) { 46 | // 买家购买商品 47 | console.log(this.name + "购买:", product); 48 | } 49 | 50 | } 51 | 52 | 53 | const shop = new Shop() 54 | 55 | const buyer1 = new Buyer('burer1') 56 | const buyer2 = new Buyer('burer2') 57 | const buyer3 = new Buyer('burer3') 58 | 59 | shop.register(buyer1) 60 | shop.register(buyer2) 61 | 62 | shop.setProduct('手机') -------------------------------------------------------------------------------- /设计模式/行为模式/responsibility.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 责任链模式 3 | * “当一个业务需要经历一系列业务对象去处理时,我们可以把这些业务对象串联起来成为一条业务责任链,” 4 | * 例如:财务审批。财务 (无权限,再到)-》经理 (无权限,再到)-》总监 5 | */ 6 | 7 | // 审批流程 8 | class Approver { 9 | constructor(name) { 10 | this.name = name 11 | this.nextApprover = null 12 | } 13 | setNextApprover(nextApprover) { 14 | this.nextApprover = nextApprover 15 | return this.nextApprover 16 | } 17 | approve(acount) { console.log('审批金额') } 18 | } 19 | 20 | // 专员 21 | class Staff extends Approver { 22 | constructor(name) { 23 | super() 24 | this.name = name 25 | } 26 | approve(acount) { 27 | if (acount < 1000) { 28 | console.log('专员审批金额通过', acount, this.name) 29 | } else { 30 | console.log('金额大,专员无法审批', this.name) 31 | this.nextApprover.approve(acount) 32 | } 33 | } 34 | } 35 | 36 | // 经理 37 | class Manager extends Approver { 38 | constructor(name) { 39 | super() 40 | this.name = name 41 | } 42 | approve(acount) { 43 | if (acount < 10000) { 44 | console.log('经理审批金额通过', acount, this.name) 45 | } else { 46 | console.log('金额大,经理无法审批', this.name) 47 | this.nextApprover.approve(acount) 48 | } 49 | } 50 | } 51 | 52 | // 总监 53 | class CEO extends Approver { 54 | constructor(name) { 55 | super() 56 | this.name = name 57 | } 58 | approve(acount) { 59 | if (acount < 100000) { 60 | console.log('CEO审批金额通过', acount, this.name) 61 | } else { 62 | console.log('公司倒闭了') 63 | } 64 | } 65 | } 66 | 67 | const staff = new Staff('李四') 68 | staff.setNextApprover(new Manager('张三')).setNextApprover(new CEO('王五')) 69 | 70 | staff.approve(15000) -------------------------------------------------------------------------------- /设计模式/行为模式/strategy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 策略模式 3 | * 强调的是行为的灵活切换, 通过添加策略行为实现灵活的实现方式 4 | * 例如: 计算 5 | */ 6 | 7 | // 接口 8 | class Strategy { 9 | calculate(a, b) { console.log(a, b) } 10 | } 11 | 12 | class Add extends Strategy { 13 | constructor() { super() } 14 | calculate(a, b) { console.log(a + b); return a + b } 15 | } 16 | 17 | class Mod extends Strategy { 18 | constructor() { super() } 19 | calculate(a, b) { console.log(a % b); return a % b } 20 | } 21 | 22 | class Calculator { 23 | 24 | constructor() { 25 | this.strategy = null 26 | } 27 | 28 | setStrategy(strategy) { 29 | this.strategy = strategy 30 | } 31 | 32 | getRuleData(a, b) { 33 | this.strategy.calculate(a, b) 34 | } 35 | 36 | } 37 | 38 | 39 | const calculator = new Calculator() 40 | 41 | calculator.setStrategy(new Add()) 42 | calculator.getRuleData(45, 12) 43 | 44 | calculator.setStrategy(new Mod()) 45 | calculator.getRuleData(4, 2) 46 | 47 | 48 | -------------------------------------------------------------------------------- /设计模式/行为模式/template.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 模板模式(提取类中公共方法) 3 | * 模板方法模式巧妙地结合了抽象类虚部方法与实部方法, 4 | * 分别定义了可变部分与不变部分,其中前者留给子类去实现,保证了系统的可扩展性; 5 | * 而后者则包含一系列对前者的逻辑调用,为子类提供了一种固有的应用指导规范。 6 | */ 7 | 8 | // 哺乳动物 抽象类 9 | class Mammal { 10 | move() {} 11 | eat() {} 12 | live() { 13 | this.move() 14 | this.eat() 15 | console.log('生活') 16 | } 17 | } 18 | 19 | // 狗 20 | class Dog extends Mammal { 21 | move() { 22 | console.log('走') 23 | } 24 | eat() { 25 | console.log('吃骨头') 26 | } 27 | } 28 | 29 | // 猫 30 | class Cat extends Mammal { 31 | move() { 32 | console.log('走') 33 | } 34 | eat() { 35 | console.log('吃猫粮') 36 | } 37 | } 38 | 39 | new Dog().live() 40 | new Cat().live() -------------------------------------------------------------------------------- /设计模式/行为模式/visitor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 访问者模式 3 | * 数据与算法的耦合问题,尤其是在数据结构比较稳定,而算法多变的情况下 4 | * 例如: 商店产品价格计算。酒水类按瓶,水果类按斤 5 | */ 6 | 7 | // 访问者抽象类 8 | class Visitor { 9 | visitor(product) { console.log(product) } 10 | } 11 | 12 | /** 产品抽象类 */ 13 | class Product { 14 | 15 | constructor(name, price) { 16 | this.name = name 17 | this.price = price 18 | } 19 | 20 | setName(name) { 21 | this.name = name 22 | } 23 | getName() { 24 | return this.name 25 | } 26 | 27 | setPrice(price) { 28 | this.price = price 29 | } 30 | 31 | getPrice() { 32 | return this.price 33 | } 34 | 35 | } 36 | 37 | 38 | /** 水果 */ 39 | class Fruit extends Product { 40 | 41 | constructor(name, price, weight) { 42 | super(name, price) 43 | this.weight = weight 44 | } 45 | 46 | setWeight(weight) { 47 | this.weight = weight 48 | } 49 | 50 | getWeight() { 51 | return this.weight 52 | } 53 | 54 | } 55 | 56 | 57 | class Wine extends Product { 58 | constructor(name, price) { 59 | super(name, price) 60 | } 61 | } 62 | 63 | class DiscountVisitor extends Visitor { 64 | visitor(product) { 65 | if (product instanceof Fruit) { 66 | console.log('Fruit') 67 | } else if (product instanceof Wine) { 68 | console.log('Wine') 69 | } 70 | } 71 | } 72 | 73 | const discountVisitor = new DiscountVisitor() 74 | discountVisitor.visitor(new Fruit('苹果', 10)) 75 | discountVisitor.visitor(new Wine('啤酒', 10)) --------------------------------------------------------------------------------