From 6986fbdc3c72fd64d59892c44a954c90b4abbbc2 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sat, 3 May 2025 15:03:25 +0800 Subject: [PATCH 1/8] disable synchronize when typeorm db init, all schema change depend on migration --- packages/sqlite-plugin/package.json | 2 +- packages/sqlite-plugin/src/index.ts | 3 +- ...1729182577167-UpdateChatStartupLogTable.ts | 46 +++++++++++-------- .../1732032381304-UpdateBossInfoTable.ts | 36 +++++++++++---- ...6092370665-AddColumnForMarkAsNotSuitLog.ts | 36 +++++++++++---- 5 files changed, 82 insertions(+), 41 deletions(-) diff --git a/packages/sqlite-plugin/package.json b/packages/sqlite-plugin/package.json index 46b9798..d61ad33 100644 --- a/packages/sqlite-plugin/package.json +++ b/packages/sqlite-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@geekgeekrun/sqlite-plugin", - "version": "0.0.1", + "version": "0.0.2", "description": "", "main": "dist/index.js", "dependencies": { diff --git a/packages/sqlite-plugin/src/index.ts b/packages/sqlite-plugin/src/index.ts index f9bf251..ad14341 100644 --- a/packages/sqlite-plugin/src/index.ts +++ b/packages/sqlite-plugin/src/index.ts @@ -1,6 +1,7 @@ import "reflect-metadata"; import { type DataSource } from "typeorm"; import { requireTypeorm } from "./utils/module-loader"; +import fs from 'node:fs' import { BossInfo } from "./entity/BossInfo"; import { BossInfoChangeLog } from "./entity/BossInfoChangeLog"; @@ -33,7 +34,7 @@ export function initDb(dbFilePath) { const { DataSource } = requireTypeorm() const appDataSource = new DataSource({ type: "sqlite", - synchronize: true, + synchronize: !fs.existsSync(dbFilePath), logging: true, logger: "simple-console", database: dbFilePath, diff --git a/packages/sqlite-plugin/src/migrations/1729182577167-UpdateChatStartupLogTable.ts b/packages/sqlite-plugin/src/migrations/1729182577167-UpdateChatStartupLogTable.ts index 9e6e1f4..972a5d4 100644 --- a/packages/sqlite-plugin/src/migrations/1729182577167-UpdateChatStartupLogTable.ts +++ b/packages/sqlite-plugin/src/migrations/1729182577167-UpdateChatStartupLogTable.ts @@ -1,19 +1,24 @@ -import { MigrationInterface, QueryRunner, TableColumn } from "typeorm"; +import { DataSource, MigrationInterface, QueryRunner, TableColumn } from "typeorm"; +import { VBossLibrary } from "../entity/VBossLibrary"; +import { VChatStartupLog } from "../entity/VChatStartupLog"; +import { VCompanyLibrary } from "../entity/VCompanyLibrary"; +import { VJobLibrary } from "../entity/VJobLibrary"; +import { VMarkAsNotSuitLog } from "../entity/VMarkAsNotSuitLog"; -const viewNames = [ - "v_boss_library", - "v_chat_startup_log", - "v_company_library", - "v_job_library", - "v_mark_as_not_suit_log" -]; +const ViewEntities = [ + VBossLibrary, + VChatStartupLog, + VCompanyLibrary, + VJobLibrary, + VMarkAsNotSuitLog, +] -export class UpdateChatStartupLogTable1729182577167 - implements MigrationInterface -{ +export class UpdateChatStartupLogTable1729182577167 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { - for (const viewName of viewNames) { - await queryRunner.query(`DROP VIEW IF EXISTS "${viewName}"`); + for (const EntityDefinition of ViewEntities) { + const dataSource = queryRunner.connection as DataSource; + const viewMetadata = dataSource.getMetadata(EntityDefinition); + await queryRunner.query(`DROP VIEW IF EXISTS "${viewMetadata.tableName}"`); } if (await queryRunner.hasTable("boss_active_status_record")) { if (await queryRunner.hasColumn("boss_active_status_record", "updateDate")) { @@ -40,14 +45,17 @@ export class UpdateChatStartupLogTable1729182577167 }) ) } + for (const EntityDefinition of ViewEntities) { + const dataSource = queryRunner.connection as DataSource; + const viewMetadata = dataSource.getMetadata(EntityDefinition); + let expression = viewMetadata.expression; + if (typeof expression === 'function') { + expression = expression(dataSource).getQuery(); + } + await queryRunner.query(`CREATE VIEW "${viewMetadata.tableName}" AS ${expression}`); + } } public async down(queryRunner: QueryRunner): Promise { - for (const viewName of viewNames) { - await queryRunner.query(`DROP VIEW IF EXISTS "${viewName}"`); - } - await queryRunner.query( - `ALTER TABLE boss_active_status_record RENAME COLUMN updateTime TO updateDate` - ); } } diff --git a/packages/sqlite-plugin/src/migrations/1732032381304-UpdateBossInfoTable.ts b/packages/sqlite-plugin/src/migrations/1732032381304-UpdateBossInfoTable.ts index 1a3a979..1f56a98 100644 --- a/packages/sqlite-plugin/src/migrations/1732032381304-UpdateBossInfoTable.ts +++ b/packages/sqlite-plugin/src/migrations/1732032381304-UpdateBossInfoTable.ts @@ -1,17 +1,24 @@ -import { MigrationInterface, QueryRunner, TableColumn } from "typeorm"; +import { DataSource, MigrationInterface, QueryRunner, TableColumn } from "typeorm"; +import { VBossLibrary } from "../entity/VBossLibrary"; +import { VChatStartupLog } from "../entity/VChatStartupLog"; +import { VCompanyLibrary } from "../entity/VCompanyLibrary"; +import { VJobLibrary } from "../entity/VJobLibrary"; +import { VMarkAsNotSuitLog } from "../entity/VMarkAsNotSuitLog"; -const viewNames = [ - "v_boss_library", - "v_chat_startup_log", - "v_company_library", - "v_job_library", - "v_mark_as_not_suit_log", -]; +const ViewEntities = [ + VBossLibrary, + VChatStartupLog, + VCompanyLibrary, + VJobLibrary, + VMarkAsNotSuitLog, +] export class UpdateBossInfoTable1732032381304 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { - for (const viewName of viewNames) { - await queryRunner.query(`DROP VIEW IF EXISTS "${viewName}"`); + for (const EntityDefinition of ViewEntities) { + const dataSource = queryRunner.connection as DataSource; + const viewMetadata = dataSource.getMetadata(EntityDefinition); + await queryRunner.query(`DROP VIEW IF EXISTS "${viewMetadata.tableName}"`); } if (await queryRunner.hasTable("boss_info")) { if (await queryRunner.hasColumn("boss_info", "encryptCompanyId")) { @@ -26,6 +33,15 @@ export class UpdateBossInfoTable1732032381304 implements MigrationInterface { ); } } + for (const EntityDefinition of ViewEntities) { + const dataSource = queryRunner.connection as DataSource; + const viewMetadata = dataSource.getMetadata(EntityDefinition); + let expression = viewMetadata.expression; + if (typeof expression === 'function') { + expression = expression(dataSource).getQuery(); + } + await queryRunner.query(`CREATE VIEW "${viewMetadata.tableName}" AS ${expression}`); + } } public async down(queryRunner: QueryRunner): Promise {} diff --git a/packages/sqlite-plugin/src/migrations/1746092370665-AddColumnForMarkAsNotSuitLog.ts b/packages/sqlite-plugin/src/migrations/1746092370665-AddColumnForMarkAsNotSuitLog.ts index 536ed7f..db98e30 100644 --- a/packages/sqlite-plugin/src/migrations/1746092370665-AddColumnForMarkAsNotSuitLog.ts +++ b/packages/sqlite-plugin/src/migrations/1746092370665-AddColumnForMarkAsNotSuitLog.ts @@ -1,17 +1,24 @@ -import { MigrationInterface, QueryRunner, TableColumn } from "typeorm"; +import { DataSource, MigrationInterface, QueryRunner, TableColumn } from "typeorm"; +import { VBossLibrary } from "../entity/VBossLibrary"; +import { VChatStartupLog } from "../entity/VChatStartupLog"; +import { VCompanyLibrary } from "../entity/VCompanyLibrary"; +import { VJobLibrary } from "../entity/VJobLibrary"; +import { VMarkAsNotSuitLog } from "../entity/VMarkAsNotSuitLog"; -const viewNames = [ - "v_boss_library", - "v_chat_startup_log", - "v_company_library", - "v_job_library", - "v_mark_as_not_suit_log", -]; +const ViewEntities = [ + VBossLibrary, + VChatStartupLog, + VCompanyLibrary, + VJobLibrary, + VMarkAsNotSuitLog, +] export class AddColumnForMarkAsNotSuitLog1746092370665 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { - for (const viewName of viewNames) { - await queryRunner.query(`DROP VIEW IF EXISTS "${viewName}"`); + for (const EntityDefinition of ViewEntities) { + const dataSource = queryRunner.connection as DataSource; + const viewMetadata = dataSource.getMetadata(EntityDefinition); + await queryRunner.query(`DROP VIEW IF EXISTS "${viewMetadata.tableName}"`); } if (await queryRunner.hasTable("mark_as_not_suit_log")) { if (!await queryRunner.hasColumn("mark_as_not_suit_log", "markOp")) { @@ -25,6 +32,15 @@ export class AddColumnForMarkAsNotSuitLog1746092370665 implements MigrationInter ); } } + for (const EntityDefinition of ViewEntities) { + const dataSource = queryRunner.connection as DataSource; + const viewMetadata = dataSource.getMetadata(EntityDefinition); + let expression = viewMetadata.expression; + if (typeof expression === 'function') { + expression = expression(dataSource).getQuery(); + } + await queryRunner.query(`CREATE VIEW "${viewMetadata.tableName}" AS ${expression}`); + } } public async down(queryRunner: QueryRunner): Promise {} From 7d2e60dfd0867c24b3c5a3b443ae82064f94d461 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sat, 3 May 2025 16:23:37 +0800 Subject: [PATCH 2/8] update company list --- .../default-config-file/target-company-list.json | 2 +- .../src/page/MainLayout/GeekAutoStartChatWithBoss.vue | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/geek-auto-start-chat-with-boss/default-config-file/target-company-list.json b/packages/geek-auto-start-chat-with-boss/default-config-file/target-company-list.json index 1fdf70e..09c0944 100644 --- a/packages/geek-auto-start-chat-with-boss/default-config-file/target-company-list.json +++ b/packages/geek-auto-start-chat-with-boss/default-config-file/target-company-list.json @@ -1,4 +1,4 @@ [ "青钱","软通动力","南天","睿服","中电金信","佰钧成","云链","博彦","汉克时代","柯莱特","拓保","亿达信息","纬创","微创","微澜","诚迈科技","法本","兆尹","诚迈","联合永道","新致软件","宇信科技","华为","德科","FESCO","科锐","科之锐", - "抖音","字节","字跳","有竹居","脸萌","头条","懂车帝","滴滴","嘀嘀","巨量引擎","小桔","网易","有道","腾讯","酷狗","酷我","阅文","搜狗","京东","沃东天骏","达达","达冠","百度","昆仑芯","小度","度小满","爱奇艺","携程","趣拿","去哪儿","集度","智图","长地万方","瑞图万方","道道通","小熊博望","理想","蔚来","顺丰","讯飞","同程","艺龙","马蜂窝","贝壳","自如","链家","我爱我家","相寓","多点","金山","小米","猎豹","新浪","微博","阿里","淘宝","淘麦郎","天猫","盒马","口碑","优视","夸克","UC","蚂蚁","高德","LAZADA","来赞达","飞猪","菜鸟","哈啰","钉钉","乌鸫","饿了么","美团","三快","猫眼","快手","映客","小红书","行吟","奇虎","360","三六零","鸿盈","奇富","奇元","亚信","启明星辰","奇安信","深信服","长亭","绿盟","天融信","商汤","SenseTime","大华","海康威视","hikvision","汽车之家","车好多","瓜子","易车","昆仑万维","昆仑天工","闲徕","趣加","FunPlus","完美","马上消费","轻松","水滴","白龙马","58","车欢欢","五八","红布林","致美","快狗","天鹅到家","转转","美餐","知乎","智者四海","易点云","搜狐","用友","畅捷通","猿辅导","小猿","猿力","好未来","学而思","希望学","新东方","东方甄选","东方优选","作业帮","高途","跟谁学","学科网","天学网","一起教育","一起作业","美术宝","火花思维","粉笔","老虎国际","一心向上","向上一意","联想","拉勾","乐视","欢聚","竞技世界","拼多多","寻梦","得物","Moka","希瑞亚斯","北森","OPPO","欧珀","vivo","维沃","小天才","步步高","读书郎","货拉拉","陌陌","探探","Shopee","首汽租车","GoFun","神州租车","天眼查","旷视","小冰","美图","智谱华章","MiniMax","石头科技","迅雷","TP","希音","SHEIN","稀宇","深言","百川智能","与爱为舞","牵手","Grab","爱回收","洋钱罐","瓴岳","得到","思维造物","地平线","咪咕","翼支付","电信","天翼","联通","蓝湖","墨刀" + "抖音","字节","字跳","有竹居","脸萌","头条","懂车帝","滴滴","嘀嘀","巨量引擎","小桔","网易","有道","腾讯","酷狗","酷我","阅文","搜狗","小鹅通","富途","京东","沃东天骏","达达","达冠","百度","昆仑芯","小度","度小满","爱奇艺","携程","趣拿","去哪儿","集度","智图","长地万方","瑞图万方","道道通","小熊博望","理想","蔚来","顺丰","丰巢","中通","圆通","申通","跨越","讯飞","同程","艺龙","马蜂窝","贝壳","自如","链家","我爱我家","相寓","多点","金山","小米","猎豹","新浪","微博","阿里","淘宝","淘麦郎","天猫","盒马","口碑","优视","夸克","UC","蚂蚁","高德","LAZADA","来赞达","飞猪","菜鸟","哈啰","钉钉","乌鸫","饿了么","美团","三快","猫眼","快手","映客","小红书","行吟","奇虎","360","三六零","鸿盈","奇富","奇元","亚信","启明星辰","奇安信","深信服","长亭","绿盟","天融信","商汤","SenseTime","大华","海康威视","hikvision","汽车之家","车好多","瓜子","易车","昆仑万维","昆仑天工","闲徕","趣加","FunPlus","完美","马上消费","轻松","水滴","白龙马","58","车欢欢","五八","红布林","致美","快狗","天鹅到家","转转","美餐","知乎","智者四海","易点云","搜狐","用友","畅捷通","猿辅导","小猿","猿力","好未来","学而思","希望学","新东方","东方甄选","东方优选","作业帮","高途","跟谁学","学科网","天学网","一起教育","一起作业","美术宝","火花思维","粉笔","51talk","爱学习","高思","老虎国际","一心向上","向上一意","联想","拉勾","乐视","欢聚","竞技世界","拼多多","寻梦","从鲸","TEMU","得物","有赞","Moka","希瑞亚斯","北森","OPPO","欧珀","vivo","维沃","小天才","步步高","读书郎","货拉拉","陌陌","探探","Shopee","虾皮","首汽租车","GoFun","神州租车","天眼查","旷视","小冰","美图","智谱华章","MiniMax","石头科技","迅雷","TP","锐捷","Tenda","腾达","斐讯","希音","SHEIN","稀宇","深言","百川智能","与爱为舞","牵手","Grab","爱回收","洋钱罐","瓴岳","得到","思维造物","地平线","咪咕","翼支付","电信","天翼","联通","蓝湖","墨刀","海尔","美的","米哈游","传音","同花顺","国美","TCL" ] \ No newline at end of file diff --git a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss.vue b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss.vue index c6ad120..4b9a96c 100644 --- a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss.vue +++ b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss.vue @@ -521,7 +521,7 @@ const expectCompanyTemplateList = [ }, { name: '大厂及关联企业', - value: `抖音,字节,字跳,有竹居,脸萌,头条,懂车帝,巨量引擎,滴滴,嘀嘀,小桔,网易,有道,腾讯,酷狗,酷我,阅文,搜狗,京东,沃东天骏,达达,达冠,百度,昆仑芯,小度,度小满,爱奇艺,携程,趣拿,去哪儿,集度,智图,长地万方,瑞图万方,道道通,小熊博望,理想,蔚来,顺丰,讯飞,同程,艺龙,马蜂窝,贝壳,自如,链家,我爱我家,相寓,多点,金山,小米,猎豹,新浪,微博,阿里,淘宝,淘麦郎,天猫,盒马,口碑,优视,夸克,UC,蚂蚁,高德,LAZADA,来赞达,飞猪,菜鸟,哈啰,钉钉,乌鸫,饿了么,美团,三快,猫眼,快手,映客,小红书,行吟,奇虎,360,三六零,鸿盈,奇富,奇元,亚信,启明星辰,奇安信,深信服,长亭,绿盟,天融信,商汤,SenseTime,大华,海康威视,hikvision,汽车之家,车好多,瓜子,易车,昆仑万维,昆仑天工,闲徕,趣加,FunPlus,完美,马上消费,轻松,水滴,白龙马,58,车欢欢,五八,红布林,致美,快狗,天鹅到家,转转,美餐,知乎,智者四海,易点云,搜狐,用友,畅捷通,猿辅导,小猿,猿力,好未来,学而思,希望学,新东方,东方甄选,东方优选,作业帮,高途,跟谁学,学科网,天学网,一起教育,一起作业,美术宝,火花思维,粉笔,老虎国际,一心向上,向上一意,联想,拉勾,乐视,欢聚,竞技世界,拼多多,寻梦,得物,Moka,希瑞亚斯,北森,OPPO,欧珀,vivo,维沃,小天才,步步高,读书郎,货拉拉,陌陌,探探,Shopee,首汽租车,GoFun,神州租车,天眼查,旷视,小冰,美图,智谱华章,MiniMax,石头科技,迅雷,TP,希音,SHEIN,稀宇,深言,百川智能,与爱为舞,牵手,Grab,爱回收,洋钱罐,瓴岳,得到,思维造物,地平线,咪咕,翼支付,电信,天翼,联通,蓝湖,墨刀` + value: `抖音,字节,字跳,有竹居,脸萌,头条,懂车帝,滴滴,嘀嘀,巨量引擎,小桔,网易,有道,腾讯,酷狗,酷我,阅文,搜狗,小鹅通,富途,京东,沃东天骏,达达,达冠,百度,昆仑芯,小度,度小满,爱奇艺,携程,趣拿,去哪儿,集度,智图,长地万方,瑞图万方,道道通,小熊博望,理想,蔚来,顺丰,丰巢,中通,圆通,申通,跨越,讯飞,同程,艺龙,马蜂窝,贝壳,自如,链家,我爱我家,相寓,多点,金山,小米,猎豹,新浪,微博,阿里,淘宝,淘麦郎,天猫,盒马,口碑,优视,夸克,UC,蚂蚁,高德,LAZADA,来赞达,飞猪,菜鸟,哈啰,钉钉,乌鸫,饿了么,美团,三快,猫眼,快手,映客,小红书,行吟,奇虎,360,三六零,鸿盈,奇富,奇元,亚信,启明星辰,奇安信,深信服,长亭,绿盟,天融信,商汤,SenseTime,大华,海康威视,hikvision,汽车之家,车好多,瓜子,易车,昆仑万维,昆仑天工,闲徕,趣加,FunPlus,完美,马上消费,轻松,水滴,白龙马,58,车欢欢,五八,红布林,致美,快狗,天鹅到家,转转,美餐,知乎,智者四海,易点云,搜狐,用友,畅捷通,猿辅导,小猿,猿力,好未来,学而思,希望学,新东方,东方甄选,东方优选,作业帮,高途,跟谁学,学科网,天学网,一起教育,一起作业,美术宝,火花思维,粉笔,51talk,爱学习,高思,老虎国际,一心向上,向上一意,联想,拉勾,乐视,欢聚,竞技世界,拼多多,寻梦,从鲸,TEMU,得物,有赞,Moka,希瑞亚斯,北森,OPPO,欧珀,vivo,维沃,小天才,步步高,读书郎,货拉拉,陌陌,探探,Shopee,虾皮,首汽租车,GoFun,神州租车,天眼查,旷视,小冰,美图,智谱华章,MiniMax,石头科技,迅雷,TP,锐捷,Tenda,腾达,斐讯,希音,SHEIN,稀宇,深言,百川智能,与爱为舞,牵手,Grab,爱回收,洋钱罐,瓴岳,得到,思维造物,地平线,咪咕,翼支付,电信,天翼,联通,蓝湖,墨刀,海尔,美的,米哈游,传音,同花顺,国美,TCL` }, { name: '阿里系', @@ -537,7 +537,7 @@ const expectCompanyTemplateList = [ }, { name: '腾讯系', - value: `腾讯,酷狗,酷我,阅文,搜狗,京东,沃东天骏,达达,达冠,美团,三快,猫眼,快手,拼多多,寻梦,Shopee,滴滴,嘀嘀,小桔` + value: `腾讯,酷狗,酷我,阅文,搜狗,小鹅通,富途,京东,沃东天骏,达达,达冠,美团,三快,猫眼,快手,拼多多,寻梦,从鲸,TEMU,Shopee,虾皮,滴滴,嘀嘀,小桔` }, { name: '外包、劳务派遣企业', From 10cd1cf11efcb7b5dd0714fc99d58195034477a3 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sat, 3 May 2025 16:50:54 +0800 Subject: [PATCH 3/8] ui-v0.5.0 --- packages/ui/package.json | 2 +- packages/ui/src/common/build-info.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/ui/package.json b/packages/ui/package.json index ca4bcfa..6126c3b 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "geekgeekrun-ui", - "version": "0.4.0", + "version": "0.5.0", "description": "Boss 炸弹 - 自动开聊Boss,助力每位打工人求职!", "main": "./out/main/index.js", "author": "geekgeekrun", diff --git a/packages/ui/src/common/build-info.json b/packages/ui/src/common/build-info.json index 74d28d6..595c229 100644 --- a/packages/ui/src/common/build-info.json +++ b/packages/ui/src/common/build-info.json @@ -1,7 +1,7 @@ { - "version": "0.4.0", - "buildVersion": 9, - "buildTime": 1745903517984, - "buildHash": "25e52530228e78c3cf78caa053c7da6bb138e5e2", + "version": "0.5.0", + "buildVersion": 10, + "buildTime": 1746262254413, + "buildHash": "7d2e60dfd0867c24b3c5a3b443ae82064f94d461", "name": "geekgeekrun-ui" } \ No newline at end of file From b5c3116c017d0bc6a71f0dc72c99849ece299cd3 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Tue, 6 May 2025 06:31:14 +0800 Subject: [PATCH 4/8] add `onlyRemindBossWithExpectJobType` option for autoReminder --- .../default-config-file/boss.json | 3 +- packages/ui/package.json | 1 + .../flow/OPEN_SETTING_WINDOW/ipc/index.ts | 9 ++-- .../flow/READ_NO_REPLY_AUTO_REMINDER/index.ts | 23 ++++++++ .../MainLayout/GeekAutoStartChatWithBoss.vue | 5 +- .../page/MainLayout/ReadNoReplyReminder.vue | 52 ++++++++++++++++++- packages/ui/src/renderer/src/utils/mitt.ts | 3 ++ pnpm-lock.yaml | 3 ++ 8 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 packages/ui/src/renderer/src/utils/mitt.ts diff --git a/packages/geek-auto-start-chat-with-boss/default-config-file/boss.json b/packages/geek-auto-start-chat-with-boss/default-config-file/boss.json index c724ced..678ca57 100644 --- a/packages/geek-auto-start-chat-with-boss/default-config-file/boss.json +++ b/packages/geek-auto-start-chat-with-boss/default-config-file/boss.json @@ -16,6 +16,7 @@ "geminiApiKey": "", "rechatContentSource": 1, "recentMessageQuantityForLlm": 8, - "rechatLlmFallback": 1 + "rechatLlmFallback": 1, + "onlyRemindBossWithExpectJobType": true } } \ No newline at end of file diff --git a/packages/ui/package.json b/packages/ui/package.json index 6126c3b..09b6be6 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -39,6 +39,7 @@ "diff": "^7.0.0", "electron-updater": "^6.1.7", "minimist": "^1.2.8", + "mitt": "^3.0.1", "node-machine-id": "^1.1.12", "pinia": "^3.0.2", "puppeteer": "20.1.0", diff --git a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts index d5c2681..bb7e1cb 100644 --- a/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts +++ b/packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts @@ -510,16 +510,15 @@ export default function initIpc() { ipcMain.handle('save-resume-content', saveResumeHandler) resumeEditorWindow?.once('closed', () => { ipcMain.removeHandler('save-resume-content') - ipcMain.removeHandler('fetch-resume-content') defer.reject(new Error('cancel')) }) - ipcMain.handle('fetch-resume-content', async () => { - const res = (await readConfigFile('resumes.json'))?.[0] - return res?.content ?? null - }) return defer.promise }) + ipcMain.handle('fetch-resume-content', async () => { + const res = (await readConfigFile('resumes.json'))?.[0] + return res?.content ?? null + }) ipcMain.on('no-reply-reminder-prompt-edit', async () => { const template = await readStorageFile(autoReminderPromptTemplateFileName, { isJson: false }) if (!template) { diff --git a/packages/ui/src/main/flow/READ_NO_REPLY_AUTO_REMINDER/index.ts b/packages/ui/src/main/flow/READ_NO_REPLY_AUTO_REMINDER/index.ts index 0e6f617..174f1bc 100644 --- a/packages/ui/src/main/flow/READ_NO_REPLY_AUTO_REMINDER/index.ts +++ b/packages/ui/src/main/flow/READ_NO_REPLY_AUTO_REMINDER/index.ts @@ -32,6 +32,10 @@ const rechatLlmFallback = readConfigFile('boss.json').autoReminder?.rechatLlmFallback ?? RECHAT_LLM_FALLBACK.SEND_LOOK_FORWARD_EMOTION +const expectJobTypeRegExpStr = readConfigFile('boss.json').expectJobTypeRegExpStr +const onlyRemindBossWithExpectJobType = + readConfigFile('boss.json').autoReminder?.onlyRemindBossWithExpectJobType ?? !!expectJobTypeRegExpStr + const dbInitPromise = initDb(getPublicDbFilePath()) export const pageMapByName: { @@ -267,6 +271,24 @@ const mainLoop = async () => { }) } await sleepWithRandomDelay(1500) + // check if expect job type match + let isExpectJobTypeMatch = true + if (onlyRemindBossWithExpectJobType) { + const selectedFriendInfo = await pageMapByName.boss?.evaluate( + `document.querySelector('.chat-conversation')?.__vue__?.selectedFriend$` + ) + if (!selectedFriendInfo) { + isExpectJobTypeMatch = false + } else { + const jobType = selectedFriendInfo?.positionName + if (!jobType) { + isExpectJobTypeMatch = false + } else { + const regExp = new RegExp(expectJobTypeRegExpStr) + isExpectJobTypeMatch = regExp.test(jobType) + } + } + } const conversationInfo = await pageMapByName.boss?.evaluate( `document.querySelector('.chat-conversation .chat-im.chat-editor')?.__vue__?.conversation$` ) @@ -280,6 +302,7 @@ const mainLoop = async () => { const lastGeekMessageSendTime = historyMessageList.findLast((it) => it.isSelf)?.time ?? 0 if ( + isExpectJobTypeMatch && historyMessageList[historyMessageList.length - 1].isSelf && historyMessageList[historyMessageList.length - 1].status === MsgStatus.HAS_READ && ((conversationInfo && diff --git a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss.vue b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss.vue index 4b9a96c..819ea12 100644 --- a/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss.vue +++ b/packages/ui/src/renderer/src/page/MainLayout/GeekAutoStartChatWithBoss.vue @@ -133,7 +133,7 @@
-
职位类型正则(不区分大小写)
+
职位类型正则(推荐填写,不区分大小写)
+ 发送提醒消息前,先按照“Boss炸弹-职位类型正则”校验正在与Boss沟通的岗位是否满足期望,校验通过后再提醒 + + + +
@@ -184,6 +208,7 @@ import { RECHAT_LLM_FALLBACK } from '../../../../common/enums/auto-start-chat' import { gtagRenderer } from '@renderer/utils/gtag' +import mittBus from '../../utils/mitt' const router = useRouter() const formContent = ref({ @@ -192,7 +217,8 @@ const formContent = ref({ rechatLimitDay: 21, rechatContentSource: 1, recentMessageQuantityForLlm: 8, - rechatLlmFallback: RECHAT_LLM_FALLBACK.SEND_LOOK_FORWARD_EMOTION + rechatLlmFallback: RECHAT_LLM_FALLBACK.SEND_LOOK_FORWARD_EMOTION, + onlyRemindBossWithExpectJobType: true } }) @@ -224,10 +250,32 @@ electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => { ? 8 : parseInt(conf.recentMessageQuantityForLlm) : 8 + conf.onlyRemindBossWithExpectJobType = conf.onlyRemindBossWithExpectJobType ?? true conf.rechatLlmFallback = conf.rechatLlmFallback ?? RECHAT_LLM_FALLBACK.SEND_LOOK_FORWARD_EMOTION formContent.value.autoReminder = conf }) +const expectJobTypeRegExpStr = ref('') +async function fetchExpectJobTypeRegExpStr() { + await electron.ipcRenderer.invoke('fetch-config-file-content').then((res) => { + expectJobTypeRegExpStr.value = res.config['boss.json']?.expectJobTypeRegExpStr + }) +} +fetchExpectJobTypeRegExpStr() +mittBus.on('auto-start-chat-with-boss-config-saved', fetchExpectJobTypeRegExpStr) +onUnmounted(() => { + mittBus.off('auto-start-chat-with-boss-config-saved', fetchExpectJobTypeRegExpStr) +}) + +const resumeContent = ref(null) +async function fetchResumeContent() { + await electron.ipcRenderer.invoke('fetch-resume-content').then((res) => { + resumeContent.value = res + }) +} + +fetchResumeContent() + const formRules = { throttleIntervalMinutes: { validator(_, value, cb) { @@ -274,6 +322,7 @@ async function checkIsCanRun() { gtagRenderer('invalid_rc_dialog_click_confirm') try { await electron.ipcRenderer.invoke('resume-edit') + await fetchResumeContent() } catch (err) { console.log(err) } @@ -449,6 +498,7 @@ const handleClickEditResume = async () => { gtagRenderer('edit_resume_clicked') try { await electron.ipcRenderer.invoke('resume-edit') + await fetchResumeContent() } catch (err) { console.log(err) } diff --git a/packages/ui/src/renderer/src/utils/mitt.ts b/packages/ui/src/renderer/src/utils/mitt.ts new file mode 100644 index 0000000..b61b745 --- /dev/null +++ b/packages/ui/src/renderer/src/utils/mitt.ts @@ -0,0 +1,3 @@ +import mitt from 'mitt' +const mittBus = mitt() +export default mittBus diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 74067c4..4402ddd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,6 +132,9 @@ importers: minimist: specifier: ^1.2.8 version: 1.2.8 + mitt: + specifier: ^3.0.1 + version: 3.0.1 node-machine-id: specifier: ^1.1.12 version: 1.1.12 From 97793adb0f75dd39a5ee4b0768a0d92587046a6c Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Thu, 8 May 2025 03:33:23 +0800 Subject: [PATCH 5/8] =?UTF-8?q?check=20message=20list=20when=20find=20last?= =?UTF-8?q?=20message=20is=20`=E5=BC=80=E5=9C=BA=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8C=E6=9C=9F=E5=BE=85=E4=BD=A0=E7=9A=84=E5=9B=9E=E7=AD=94?= =?UTF-8?q?`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/src/main/flow/READ_NO_REPLY_AUTO_REMINDER/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/main/flow/READ_NO_REPLY_AUTO_REMINDER/index.ts b/packages/ui/src/main/flow/READ_NO_REPLY_AUTO_REMINDER/index.ts index 174f1bc..0560f55 100644 --- a/packages/ui/src/main/flow/READ_NO_REPLY_AUTO_REMINDER/index.ts +++ b/packages/ui/src/main/flow/READ_NO_REPLY_AUTO_REMINDER/index.ts @@ -121,7 +121,6 @@ const mainLoop = async () => { '你与该职位竞争者PK情况', '简历诊断提醒', '附件简历还没准备好', - '开场问题,期待你的回答', '设置合适的期望薪资范围' ].map((it) => new RegExp(it)) browser = await bootstrap() @@ -202,9 +201,10 @@ const mainLoop = async () => { (rechatLimitDay && it.updateTime ? +new Date() - it.updateTime < rechatLimitDay * 24 * 60 * 60 * 1000 : true) && - ((it.lastIsSelf && it.lastMsgStatus === MsgStatus.HAS_READ) || + ((((it.lastIsSelf && it.lastMsgStatus === MsgStatus.HAS_READ) || canNotConfirmIfHasReadMsgTemplateList.some((regExp) => regExp.test(it.lastText))) && - !it.unreadCount + !it.unreadCount) || + (!it.lastIsSelf && it.lastText === '开场问题,期待你的回答')) ) }) From ece7fc61e3788ecd7847b543c5dcbbe5f9cd8f0b Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Thu, 8 May 2025 03:35:30 +0800 Subject: [PATCH 6/8] ui-v0.6.0 --- packages/ui/package.json | 2 +- packages/ui/src/common/build-info.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/ui/package.json b/packages/ui/package.json index 09b6be6..f1b50b6 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "geekgeekrun-ui", - "version": "0.5.0", + "version": "0.6.0", "description": "Boss 炸弹 - 自动开聊Boss,助力每位打工人求职!", "main": "./out/main/index.js", "author": "geekgeekrun", diff --git a/packages/ui/src/common/build-info.json b/packages/ui/src/common/build-info.json index 595c229..7da6b5a 100644 --- a/packages/ui/src/common/build-info.json +++ b/packages/ui/src/common/build-info.json @@ -1,7 +1,7 @@ { - "version": "0.5.0", - "buildVersion": 10, - "buildTime": 1746262254413, - "buildHash": "7d2e60dfd0867c24b3c5a3b443ae82064f94d461", + "version": "0.6.0", + "buildVersion": 11, + "buildTime": 1746646530387, + "buildHash": "97793adb0f75dd39a5ee4b0768a0d92587046a6c", "name": "geekgeekrun-ui" } \ No newline at end of file From 61c28ae1646c3cea900eae62acdd91b54a677508 Mon Sep 17 00:00:00 2001 From: geekgeekrun Date: Sat, 10 May 2025 23:04:07 +0800 Subject: [PATCH 7/8] fix error popped when first run and init db --- packages/sqlite-plugin/src/index.ts | 4 +++- .../src/migrations/1000000000000-Init.ts | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 packages/sqlite-plugin/src/migrations/1000000000000-Init.ts diff --git a/packages/sqlite-plugin/src/index.ts b/packages/sqlite-plugin/src/index.ts index ad14341..2940b04 100644 --- a/packages/sqlite-plugin/src/index.ts +++ b/packages/sqlite-plugin/src/index.ts @@ -29,12 +29,13 @@ import minimist from 'minimist' import { UpdateBossInfoTable1732032381304 } from "./migrations/1732032381304-UpdateBossInfoTable"; import { MarkAsNotSuitOp, MarkAsNotSuitReason } from "./enums"; import { AddColumnForMarkAsNotSuitLog1746092370665 } from "./migrations/1746092370665-AddColumnForMarkAsNotSuitLog"; +import { Init1000000000000 } from "./migrations/1000000000000-Init"; export function initDb(dbFilePath) { const { DataSource } = requireTypeorm() const appDataSource = new DataSource({ type: "sqlite", - synchronize: !fs.existsSync(dbFilePath), + synchronize: false, logging: true, logger: "simple-console", database: dbFilePath, @@ -60,6 +61,7 @@ export function initDb(dbFilePath) { LlmModelUsageRecord, ], migrations: [ + Init1000000000000, UpdateChatStartupLogTable1729182577167, UpdateBossInfoTable1732032381304, AddColumnForMarkAsNotSuitLog1746092370665, diff --git a/packages/sqlite-plugin/src/migrations/1000000000000-Init.ts b/packages/sqlite-plugin/src/migrations/1000000000000-Init.ts new file mode 100644 index 0000000..bc323d6 --- /dev/null +++ b/packages/sqlite-plugin/src/migrations/1000000000000-Init.ts @@ -0,0 +1,24 @@ +import { DataSource, MigrationInterface, QueryRunner, TableColumn } from "typeorm"; +export class Init1000000000000 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + const tableSchemaStatements = `CREATE TABLE IF NOT EXISTS "boss_info" ("encryptBossId" varchar PRIMARY KEY NOT NULL, "encryptCompanyId" varchar, "name" varchar NOT NULL, "date" datetime NOT NULL, "title" varchar NOT NULL); +CREATE TABLE IF NOT EXISTS "boss_info_change_log" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "encryptBossId" varchar NOT NULL, "updateTime" datetime NOT NULL, "dataAsJson" varchar NOT NULL); +CREATE TABLE IF NOT EXISTS "chat_startup_log" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "encryptJobId" varchar NOT NULL, "encryptCurrentUserId" varchar NOT NULL, "date" datetime NOT NULL, "chatStartupFrom" integer, "autoStartupChatRecordId" integer); +CREATE TABLE IF NOT EXISTS "company_info_change_log" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "encryptCompanyId" varchar NOT NULL, "updateTime" datetime NOT NULL, "dataAsJson" varchar NOT NULL); +CREATE TABLE IF NOT EXISTS "company_info" ("encryptCompanyId" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, "brandName" varchar NOT NULL, "scaleLow" integer, "scaleHigh" integer, "stageName" varchar, "industryName" varchar); +CREATE TABLE IF NOT EXISTS "job_info" ("encryptJobId" varchar PRIMARY KEY NOT NULL, "jobName" varchar NOT NULL, "positionName" varchar NOT NULL, "salaryLow" integer, "salaryHigh" integer, "salaryMonth" integer, "experienceName" varchar NOT NULL, "publishDate" datetime, "degreeName" varchar, "address" varchar, "description" varchar NOT NULL, "encryptBossId" varchar NOT NULL, "encryptCompanyId" varchar NOT NULL); +CREATE TABLE IF NOT EXISTS "job_info_change_log" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "encryptJobId" varchar NOT NULL, "updateTime" datetime NOT NULL, "dataAsJson" varchar NOT NULL); +CREATE TABLE IF NOT EXISTS "boss_active_status_record" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "encryptBossId" varchar NOT NULL, "lastActiveStatus" varchar, "updateTime" datetime NOT NULL); +CREATE TABLE IF NOT EXISTS "user_info" ("encryptUserId" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL); +CREATE TABLE IF NOT EXISTS "auto_start_chat_run_record" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "date" datetime NOT NULL); +CREATE TABLE IF NOT EXISTS "mark_as_not_suit_log" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "encryptJobId" varchar NOT NULL, "encryptCurrentUserId" varchar NOT NULL, "date" datetime NOT NULL, "markFrom" integer, "markReason" integer, "extInfo" varchar, "autoStartupChatRecordId" integer); +CREATE TABLE IF NOT EXISTS "chat_message_record" ("mid" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "encryptFromUserId" varchar NOT NULL, "encryptToUserId" varchar NOT NULL, "time" datetime, "type" varchar, "style" varchar, "text" varchar, "imageUrl" varchar, "imageWidth" integer, "imageHeight" integer); +CREATE TABLE IF NOT EXISTS "llm_model_usage_record" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "providerCompleteApiUrl" varchar NOT NULL, "model" varchar NOT NULL, "providerApiSecret" varchar, "completionTokens" integer, "promptTokens" integer, "promptCacheHitTokens" integer, "promptCacheMissTokens" integer, "totalTokens" integer, "requestStartTime" datetime NOT NULL, "requestEndTime" datetime, "hasError" boolean NOT NULL, "errorMessage" varchar NOT NULL, "requestScene" integer);`.split('\n') + for(const statement of tableSchemaStatements) { + await queryRunner.query(statement); + } + } + + public async down(queryRunner: QueryRunner): Promise { + } +} From 6982f6028d08977858f471b417f655734f0e31a9 Mon Sep 17 00:00:00 2001 From: geekgeekrun-maintainer <166113191+geekgeekrun-maintainer@users.noreply.github.com> Date: Sat, 17 May 2025 17:38:40 +0800 Subject: [PATCH 8/8] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index f2a72dc..095f216 100644 --- a/README.md +++ b/README.md @@ -166,3 +166,11 @@ Boss不明原因已读不回?简历就是投不出去? 更多功能还在开发中~ 祝你求职成功,事业顺利,事事顺心 + +## Star 数据 感谢支持 + + + + + Star History Chart +