1
This commit is contained in:
544
_doc/消息.md
Normal file
544
_doc/消息.md
Normal file
@@ -0,0 +1,544 @@
|
|||||||
|
messages[
|
||||||
|
{
|
||||||
|
"uncount": 1,
|
||||||
|
"flag": 0,
|
||||||
|
"bizType": 21050003,
|
||||||
|
"mid": 306388872406018,
|
||||||
|
"received": true,
|
||||||
|
"securityId": "cVB1gt2iMS_FV-B1EuTtuprq9nPmk046hua_alhFbU9irJdmTCNqWxiCzyABGAJxRhHJ19omwFtTF62aNLx0Kb-jEBjLnK5zAvB5QJQ74XNKfm3GvYbAw6Hat_UPGUYrWuoC78uf6-i_4mQDfnri1cgi33PGu4t76fHCBmlQgeyNQYZtvlemjQ~~",
|
||||||
|
"cmid": 0,
|
||||||
|
"type": 3,
|
||||||
|
"body": {
|
||||||
|
"type": 8,
|
||||||
|
"templateId": 1,
|
||||||
|
"jobDesc": {
|
||||||
|
"education": "本科",
|
||||||
|
"boss": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"distance": "",
|
||||||
|
"city": "上海 浦东新区 北蔡",
|
||||||
|
"lid": "",
|
||||||
|
"partTimeDesc": "",
|
||||||
|
"expectId": 1421763565,
|
||||||
|
"title": "信息系统产品经理",
|
||||||
|
"salary": "20-30K",
|
||||||
|
"experience": "3-5年",
|
||||||
|
"bottomText": "2月1日 18:19 由你发起的沟通",
|
||||||
|
"content": "",
|
||||||
|
"jobLabel": "",
|
||||||
|
"latlon": "",
|
||||||
|
"expectPosition": "",
|
||||||
|
"company": "中建八局上海公司",
|
||||||
|
"url": "bosszp://bosszhipin.app/openwith?type=jobview&jid=510160286&uid=631237132&securityId=_gWIU90mUoEub-b1Uw8xol50QDeii-lYj5J6gGaUDpLqCFr6_7TAHagl3UwLBh3S8tgBUY_91xh-LMPqDo56Bhg2tM5ptshBG4OSYvjb2szm9uGWm64E8GFe2pIXtMoJJW53RY_enX-0S41IAQyZSwBHGDLKYC-ajb88mwLIgFzHv26-aCA6uQXewrLCx0JKQZdIcGdUYOLlbbjVOXgCwPV04Ih_o6_BUwTq8iZjpMMBSuMa_abda3A_rjsOeY_qaN0tPcB92T2m3a0xMseYDQyJQj6x8CqTN3Wn8NhF3RuYC3KvDRGYC22HGNfGIHRHIbXlOIm5N6HK6UFRkfQMoYIl6KIJOm9-q3mHf4exItvw1_K8ArABDBF2koQ0lyCMu0bvrscAuUZCY4ggK_r4iUNaJz-r7mvO5JLona10LTHVmZ5gRGXej4kIPT9F2lj02KdK0nKWG8ilYQ2AzD0FbUI52lYa5CgAu5hhO9_kHcsJdfhxKCaSbiM_To6iTrJtfEksQnmqwMLU6tpTw-N3SA-UJsXfhwJRV3uhDsKGJeIFDpJjZ6IFr3qVVIDzwROyUZlK6Tu8Y8_nnKHxrtuIKfQPU8mFrWf02LtWWJg~",
|
||||||
|
"extend": "{\"jobType\":0}",
|
||||||
|
"jobId": 510160286,
|
||||||
|
"stage": "未融资",
|
||||||
|
"geek": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 0,
|
||||||
|
"name": "",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"iconFlag": 0,
|
||||||
|
"positionCategory": "产品经理",
|
||||||
|
"bossTitle": "招聘主管",
|
||||||
|
"expectSalary": ""
|
||||||
|
},
|
||||||
|
"headTitle": "您正在与Boss韩先生直接沟通如下职位"
|
||||||
|
},
|
||||||
|
"offline": false,
|
||||||
|
"pushSound": 0,
|
||||||
|
"from": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 15,
|
||||||
|
"name": "肖伟民",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_15.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"time": 1769941171000,
|
||||||
|
"taskId": 0,
|
||||||
|
"status": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uncount": 0,
|
||||||
|
"flag": 0,
|
||||||
|
"bizType": 101,
|
||||||
|
"mid": 306388872410117,
|
||||||
|
"received": true,
|
||||||
|
"securityId": "HGFvURTQnW2V8-_1M1FQeOyKfMqBVGmx4iYXvV-ja6Ax2OHah-vLgPuQbHIZIxOV9DTQVpbE4IDFvjkbMEeBVFun5rsz1N-55pIQUpuqzGCHJTPKTSH6pYKpFoUtSueouw04tw~~",
|
||||||
|
"cmid": 0,
|
||||||
|
"type": 3,
|
||||||
|
"body": {
|
||||||
|
"extend": "",
|
||||||
|
"text": "您正在招的信息系统产品经理我很有兴趣,如果方便,希望可以和您进一步沟通,谢谢!",
|
||||||
|
"type": 1,
|
||||||
|
"templateId": 1,
|
||||||
|
"headTitle": ""
|
||||||
|
},
|
||||||
|
"offline": false,
|
||||||
|
"pushSound": 0,
|
||||||
|
"bizId": "42",
|
||||||
|
"from": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 15,
|
||||||
|
"name": "肖伟民",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_15.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"time": 1769941171000,
|
||||||
|
"pushText": "肖伟民:您正在招的信息系统产品经理我很有兴趣,如果方便,希望可以和您进一步沟通,谢谢!",
|
||||||
|
"taskId": 0,
|
||||||
|
"status": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uncount": 1,
|
||||||
|
"flag": 0,
|
||||||
|
"bizType": 317,
|
||||||
|
"mid": 306388872438784,
|
||||||
|
"received": true,
|
||||||
|
"securityId": "scWxOY-tkn0ih-A1bkgY7cd1djlTDxgd7J24wQXQqZvi8wn_teicgd2zAj7dz74o5LYrEdUJsKDHzdyUzdqrWs55p9cUQXsroGgVJrQlUspiITmPBY23-nVeei7VytBBuFATuw~~",
|
||||||
|
"cmid": 0,
|
||||||
|
"type": 4,
|
||||||
|
"body": {
|
||||||
|
"style": 3,
|
||||||
|
"type": 16,
|
||||||
|
"templateId": 1,
|
||||||
|
"articles": [
|
||||||
|
{
|
||||||
|
"extend": "{\"descriptionHighParts\":[{\"endIndex\":8,\"startIndex\":6},{\"endIndex\":14,\"startIndex\":12}],\"avatarList\":[\"https://img.bosszhipin.com/beijin/upload/item/20221117/e84be512208dcc09095058edb5e6d5d9273d3250d5a0c4c56bb61e3b7bce0931da574d19d1d82c88.png\",\"https://img.bosszhipin.com/beijin/upload/item/20221117/e84be512208dcc09ba9684830b5f873d7f98f2d5757b12c86bb61e3b7bce0931da574d19d1d82c88.png\",\"https://img.bosszhipin.com/beijin/upload/item/20221117/e84be512208dcc09f663dc109c9552b92d74732363d6a4056bb61e3b7bce0931da574d19d1d82c88.png\"]}",
|
||||||
|
"picUrl": "https://img.bosszhipin.com/beijin/icon/bed51f39faf420a15620181baffee482f7aba6f40b0808dd3b1d96fc3abbc5af.png",
|
||||||
|
"highlightParts": [
|
||||||
|
{
|
||||||
|
"startIndex": 1,
|
||||||
|
"endIndex": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startIndex": 10,
|
||||||
|
"endIndex": 12
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subTitle": "共**人投递,你超过**竞争者",
|
||||||
|
"description": "优秀竞争者会**,建议你**",
|
||||||
|
"statisticParameters": "",
|
||||||
|
"title": "你与该职位竞争者PK情况",
|
||||||
|
"templateId": 5,
|
||||||
|
"url": "https://m.zhipin.com/mpa/html/props/transit?targetId=a875d648fa6db1490nV62tu9ElpW&sendNum=1&bossId=5e86870fd010f0eb0Xd72d66EVFS",
|
||||||
|
"bottomText": "查看详细分析",
|
||||||
|
"timeout": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"headTitle": ""
|
||||||
|
},
|
||||||
|
"offline": false,
|
||||||
|
"pushSound": 0,
|
||||||
|
"from": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 15,
|
||||||
|
"name": "肖伟民",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_15.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"time": 1769941171000,
|
||||||
|
"pushText": "你与该职位竞争者PK情况",
|
||||||
|
"taskId": 0,
|
||||||
|
"status": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uncount": 0,
|
||||||
|
"flag": 0,
|
||||||
|
"bizType": 110,
|
||||||
|
"mid": 306962385814530,
|
||||||
|
"received": true,
|
||||||
|
"securityId": "2Qs1rcvXn2axz-Z1F_qA9Hr2oJm3oy4XqZZxP3u_iQc1b13a9hYHxYzEYHGRR5iffvX9fV3HQ02WePxjcHPZ3H2gHkLE2kI8aSRvEYf18TcPjNkA7nR8bBL75uun6ErmddoTvQ~~",
|
||||||
|
"cmid": 0,
|
||||||
|
"type": 3,
|
||||||
|
"body": {
|
||||||
|
"extend": "",
|
||||||
|
"text": "我们感谢您的投递,但您的专业技能与我们目前的职位需求并不完全吻合。祝您在BOSS直聘找到更适合您的工作!",
|
||||||
|
"type": 1,
|
||||||
|
"templateId": 1,
|
||||||
|
"headTitle": ""
|
||||||
|
},
|
||||||
|
"offline": false,
|
||||||
|
"pushSound": 0,
|
||||||
|
"from": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 15,
|
||||||
|
"name": "肖伟民",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_15.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"time": 1770081189000,
|
||||||
|
"pushText": "韩先生:我们感谢您的投递,但您的专业技能与我们目前的职位需求并不完全吻合。祝您在BOSS直聘找到更适合您的工作!",
|
||||||
|
"taskId": 0,
|
||||||
|
"status": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uncount": 0,
|
||||||
|
"flag": 0,
|
||||||
|
"mid": 307012846076929,
|
||||||
|
"received": true,
|
||||||
|
"securityId": "G91RCDcRlfd6n-Y1v0PcuW2JmcEY6RpuBJKIAI3ODWIfRD2XePO7K6i_APp7VZlOzCXxU_Scck1oUQ9TfKG1gGr0ym8Ar0yFmsCud7dQJOCe6v9PnHym2ahnoRR9Z0DILSr7XA~~",
|
||||||
|
"cmid": 4611687788520895950,
|
||||||
|
"type": 1,
|
||||||
|
"body": {
|
||||||
|
"extend": "",
|
||||||
|
"text": "好的,谢谢您的时间!",
|
||||||
|
"type": 1,
|
||||||
|
"templateId": 1,
|
||||||
|
"headTitle": ""
|
||||||
|
},
|
||||||
|
"offline": false,
|
||||||
|
"pushSound": 0,
|
||||||
|
"from": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 15,
|
||||||
|
"name": "肖伟民",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_15.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"time": 1770093508000,
|
||||||
|
"pushText": "肖伟民:好的,谢谢您的时间!",
|
||||||
|
"taskId": 0,
|
||||||
|
"status": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"uncount": 1,
|
||||||
|
"flag": 0,
|
||||||
|
"bizType": 21050003,
|
||||||
|
"mid": 306388872406018,
|
||||||
|
"received": true,
|
||||||
|
"securityId": "l6FAuQDH5EgEB-Z1zJPUxoiSUg2Z9523Jp_in3wnvBpa97RjDD49bO-Acv9BDLEXoAlWVRufC9SHOXAYZJooF7jwLsgm5Lv3ez-EX_utlkxCIW6po1_ncoGdjyT9qh7wajk-5UjNNTGpCuszVaoArX4VKt6S1O-YlMotVz0eILByZhvb1DBbmA~~",
|
||||||
|
"cmid": 0,
|
||||||
|
"type": 3,
|
||||||
|
"body": {
|
||||||
|
"type": 8,
|
||||||
|
"templateId": 1,
|
||||||
|
"jobDesc": {
|
||||||
|
"education": "本科",
|
||||||
|
"boss": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"distance": "",
|
||||||
|
"city": "上海 浦东新区 北蔡",
|
||||||
|
"lid": "",
|
||||||
|
"partTimeDesc": "",
|
||||||
|
"expectId": 1421763565,
|
||||||
|
"title": "信息系统产品经理",
|
||||||
|
"salary": "20-30K",
|
||||||
|
"experience": "3-5年",
|
||||||
|
"bottomText": "2月1日 18:19 由你发起的沟通",
|
||||||
|
"content": "",
|
||||||
|
"jobLabel": "",
|
||||||
|
"latlon": "",
|
||||||
|
"expectPosition": "",
|
||||||
|
"company": "中建八局上海公司",
|
||||||
|
"url": "bosszp://bosszhipin.app/openwith?type=jobview&jid=510160286&uid=631237132&securityId=_gWIU90mUoEub-b1Uw8xol50QDeii-lYj5J6gGaUDpLqCFr6_7TAHagl3UwLBh3S8tgBUY_91xh-LMPqDo56Bhg2tM5ptshBG4OSYvjb2szm9uGWm64E8GFe2pIXtMoJJW53RY_enX-0S41IAQyZSwBHGDLKYC-ajb88mwLIgFzHv26-aCA6uQXewrLCx0JKQZdIcGdUYOLlbbjVOXgCwPV04Ih_o6_BUwTq8iZjpMMBSuMa_abda3A_rjsOeY_qaN0tPcB92T2m3a0xMseYDQyJQj6x8CqTN3Wn8NhF3RuYC3KvDRGYC22HGNfGIHRHIbXlOIm5N6HK6UFRkfQMoYIl6KIJOm9-q3mHf4exItvw1_K8ArABDBF2koQ0lyCMu0bvrscAuUZCY4ggK_r4iUNaJz-r7mvO5JLona10LTHVmZ5gRGXej4kIPT9F2lj02KdK0nKWG8ilYQ2AzD0FbUI52lYa5CgAu5hhO9_kHcsJdfhxKCaSbiM_To6iTrJtfEksQnmqwMLU6tpTw-N3SA-UJsXfhwJRV3uhDsKGJeIFDpJjZ6IFr3qVVIDzwROyUZlK6Tu8Y8_nnKHxrtuIKfQPU8mFrWf02LtWWJg~",
|
||||||
|
"extend": "{\"jobType\":0}",
|
||||||
|
"jobId": 510160286,
|
||||||
|
"stage": "未融资",
|
||||||
|
"geek": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 0,
|
||||||
|
"name": "",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"iconFlag": 0,
|
||||||
|
"positionCategory": "产品经理",
|
||||||
|
"bossTitle": "招聘主管",
|
||||||
|
"expectSalary": ""
|
||||||
|
},
|
||||||
|
"headTitle": "您正在与Boss韩先生直接沟通如下职位"
|
||||||
|
},
|
||||||
|
"offline": false,
|
||||||
|
"pushSound": 0,
|
||||||
|
"from": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 15,
|
||||||
|
"name": "肖伟民",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_15.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"time": 1769941171000,
|
||||||
|
"taskId": 0,
|
||||||
|
"status": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uncount": 0,
|
||||||
|
"flag": 0,
|
||||||
|
"bizType": 101,
|
||||||
|
"mid": 306388872410117,
|
||||||
|
"received": true,
|
||||||
|
"securityId": "ICqTpLTj9ZNwJ-z1EH0JV5QdmFoLScV7hG92WmVbwh8OOUMHjLT1wI49GP2NbxQ0XgOl0BWmE32TShuCnB7aBYL2Tmu5w_OLGAZWHy4iwex-v68JL6m90raPWD-xJK7PFUshRA~~",
|
||||||
|
"cmid": 0,
|
||||||
|
"type": 3,
|
||||||
|
"body": {
|
||||||
|
"extend": "",
|
||||||
|
"text": "您正在招的信息系统产品经理我很有兴趣,如果方便,希望可以和您进一步沟通,谢谢!",
|
||||||
|
"type": 1,
|
||||||
|
"templateId": 1,
|
||||||
|
"headTitle": ""
|
||||||
|
},
|
||||||
|
"offline": false,
|
||||||
|
"pushSound": 0,
|
||||||
|
"bizId": "42",
|
||||||
|
"from": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 15,
|
||||||
|
"name": "肖伟民",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_15.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"time": 1769941171000,
|
||||||
|
"pushText": "肖伟民:您正在招的信息系统产品经理我很有兴趣,如果方便,希望可以和您进一步沟通,谢谢!",
|
||||||
|
"taskId": 0,
|
||||||
|
"status": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uncount": 1,
|
||||||
|
"flag": 0,
|
||||||
|
"bizType": 317,
|
||||||
|
"mid": 306388872438784,
|
||||||
|
"received": true,
|
||||||
|
"securityId": "hzKRrkb1wHEAg-p1U4iTIhg_RchIKhXZ3wxOSwcIOUeWiGyipwyvAYQhZ_2yYcMrYEcZnDiGkOFlXW23Z4qMV8SxSbBx3UlHZtnh1OQLLCnzC8BOANRVYRHOieH82O44gBThQw~~",
|
||||||
|
"cmid": 0,
|
||||||
|
"type": 4,
|
||||||
|
"body": {
|
||||||
|
"style": 3,
|
||||||
|
"type": 16,
|
||||||
|
"templateId": 1,
|
||||||
|
"articles": [
|
||||||
|
{
|
||||||
|
"extend": "{\"descriptionHighParts\":[{\"endIndex\":8,\"startIndex\":6},{\"endIndex\":14,\"startIndex\":12}],\"avatarList\":[\"https://img.bosszhipin.com/beijin/upload/item/20221117/e84be512208dcc09095058edb5e6d5d9273d3250d5a0c4c56bb61e3b7bce0931da574d19d1d82c88.png\",\"https://img.bosszhipin.com/beijin/upload/item/20221117/e84be512208dcc09ba9684830b5f873d7f98f2d5757b12c86bb61e3b7bce0931da574d19d1d82c88.png\",\"https://img.bosszhipin.com/beijin/upload/item/20221117/e84be512208dcc09f663dc109c9552b92d74732363d6a4056bb61e3b7bce0931da574d19d1d82c88.png\"]}",
|
||||||
|
"picUrl": "https://img.bosszhipin.com/beijin/icon/bed51f39faf420a15620181baffee482f7aba6f40b0808dd3b1d96fc3abbc5af.png",
|
||||||
|
"highlightParts": [
|
||||||
|
{
|
||||||
|
"startIndex": 1,
|
||||||
|
"endIndex": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startIndex": 10,
|
||||||
|
"endIndex": 12
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subTitle": "共**人投递,你超过**竞争者",
|
||||||
|
"description": "优秀竞争者会**,建议你**",
|
||||||
|
"statisticParameters": "",
|
||||||
|
"title": "你与该职位竞争者PK情况",
|
||||||
|
"templateId": 5,
|
||||||
|
"url": "https://m.zhipin.com/mpa/html/props/transit?targetId=a875d648fa6db1490nV62tu9ElpW&sendNum=1&bossId=5e86870fd010f0eb0Xd72d66EVFS",
|
||||||
|
"bottomText": "查看详细分析",
|
||||||
|
"timeout": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"headTitle": ""
|
||||||
|
},
|
||||||
|
"offline": false,
|
||||||
|
"pushSound": 0,
|
||||||
|
"from": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 15,
|
||||||
|
"name": "肖伟民",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_15.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"time": 1769941171000,
|
||||||
|
"pushText": "你与该职位竞争者PK情况",
|
||||||
|
"taskId": 0,
|
||||||
|
"status": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uncount": 0,
|
||||||
|
"flag": 0,
|
||||||
|
"bizType": 110,
|
||||||
|
"mid": 306962385814530,
|
||||||
|
"received": true,
|
||||||
|
"securityId": "6NQl3ioceNxKx-G1nOrvVjeUEQLy_S6KIErL7eOTqON2kEHVzdEw36KXlKU6wBXG4VTP227-XF9M5Ge8BKcS7BDkxqAzgrfNBxKsCZhXOlsiGlCe-SshPg43KJ1SmrpXrJa3ow~~",
|
||||||
|
"cmid": 0,
|
||||||
|
"type": 3,
|
||||||
|
"body": {
|
||||||
|
"extend": "",
|
||||||
|
"text": "我们感谢您的投递,但您的专业技能与我们目前的职位需求并不完全吻合。祝您在BOSS直聘找到更适合您的工作!",
|
||||||
|
"type": 1,
|
||||||
|
"templateId": 1,
|
||||||
|
"headTitle": ""
|
||||||
|
},
|
||||||
|
"offline": false,
|
||||||
|
"pushSound": 0,
|
||||||
|
"from": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 15,
|
||||||
|
"name": "肖伟民",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_15.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"time": 1770081189000,
|
||||||
|
"pushText": "韩先生:我们感谢您的投递,但您的专业技能与我们目前的职位需求并不完全吻合。祝您在BOSS直聘找到更适合您的工作!",
|
||||||
|
"taskId": 0,
|
||||||
|
"status": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uncount": 0,
|
||||||
|
"flag": 0,
|
||||||
|
"mid": 307012846076929,
|
||||||
|
"received": true,
|
||||||
|
"securityId": "HOZrJc7V5lAgt-I1xBVW4AIzOdmJyVezMBCstpqbYRgw8N23mSYYlslQXE15U9gbK7-EBHJcUbnhQSRF6VIrp4rZlOUgB2cMB9qz09C4DXUYv7SVELEU8i89_0YZqXlDdMq8pg~~",
|
||||||
|
"cmid": 4611687788520895950,
|
||||||
|
"type": 1,
|
||||||
|
"body": {
|
||||||
|
"extend": "",
|
||||||
|
"text": "好的,谢谢您的时间!",
|
||||||
|
"type": 1,
|
||||||
|
"templateId": 1,
|
||||||
|
"headTitle": ""
|
||||||
|
},
|
||||||
|
"offline": false,
|
||||||
|
"pushSound": 0,
|
||||||
|
"from": {
|
||||||
|
"uid": 546224865,
|
||||||
|
"headImg": 15,
|
||||||
|
"name": "肖伟民",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_15.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"to": {
|
||||||
|
"uid": 631237132,
|
||||||
|
"headImg": 7,
|
||||||
|
"name": "韩先生",
|
||||||
|
"company": "",
|
||||||
|
"avatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png",
|
||||||
|
"source": 0,
|
||||||
|
"certification": 0
|
||||||
|
},
|
||||||
|
"time": 1770093508000,
|
||||||
|
"pushText": "肖伟民:好的,谢谢您的时间!",
|
||||||
|
"taskId": 0,
|
||||||
|
"status": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
const ai_service = require('../../../services/ai_service');
|
const ai_service = require('../../../services/ai_service');
|
||||||
|
const db = require('../../dbProxy');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 聊天管理模块
|
* 聊天管理模块
|
||||||
@@ -63,13 +64,13 @@ class ChatManager {
|
|||||||
|
|
||||||
|
|
||||||
// 存储数据库
|
// 存储数据库
|
||||||
|
|
||||||
|
|
||||||
console.log(`[聊天管理] 成功获取聊天列表,共 ${parsed.friendList.length} 个联系人`);
|
console.log(`[聊天管理] 成功获取聊天列表,共 ${parsed.friendList.length} 个联系人`);
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析 get_chat_detail 设备端返回格式
|
* 解析 get_chat_detail 设备端返回格式
|
||||||
* 格式: { type, code, message, data: { success, apiData: { response: { zpData } }, getBossData: { response: { zpData } } } }
|
* 格式: { type, code, message, data: { success, apiData: { response: { zpData } }, getBossData: { response: { zpData } } } }
|
||||||
@@ -195,21 +196,63 @@ class ChatManager {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 是否为系统/模板消息(竞争者PK、拒绝模板、系统卡片等),不参与回复判断 */
|
||||||
|
_isSystemMessage(msg) {
|
||||||
|
const body = msg.body || {};
|
||||||
|
if (msg.bizType === 317 || msg.bizType === 21050003) return true;
|
||||||
|
if (msg.type === 4) return true;
|
||||||
|
if (body.type === 16) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 过滤出 HR 发的、非系统、可回复的消息列表(已排除自己发的) */
|
||||||
|
_filterHrReplyableMessages(messages, geek_uid) {
|
||||||
|
if (!geek_uid || !Array.isArray(messages)) return [];
|
||||||
|
let list = messages.filter(msg => {
|
||||||
|
if (!msg.from || msg.from.uid === geek_uid) return false;
|
||||||
|
if (this._isSystemMessage(msg)) return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return list
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** AI 回复后写入 chat_reply_intent_log,options 含 sn_code/platform/friendId/encryptFriendId 时落库 */
|
||||||
|
_saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, replied, reason) {
|
||||||
|
if (!options || options.sn_code == null) return;
|
||||||
|
try {
|
||||||
|
const model = db.getModel('chat_reply_intent_log');
|
||||||
|
model.create({
|
||||||
|
sn_code: options.sn_code || '',
|
||||||
|
platform: options.platform || 'boss',
|
||||||
|
friendId: options.friendId ?? null,
|
||||||
|
encrypt_friend_id: options.encryptFriendId || '',
|
||||||
|
hr_message_text: hr_message_text || null,
|
||||||
|
action: action || '',
|
||||||
|
reply_content: reply_content || null,
|
||||||
|
replied: !!replied,
|
||||||
|
reason: reason || null,
|
||||||
|
job_name: (jobInfo && (jobInfo.jobName || jobInfo.title)) || null,
|
||||||
|
create_time: new Date()
|
||||||
|
}).catch(e => console.warn('[聊天管理] 写入 chat_reply_intent_log 失败:', e.message));
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[聊天管理] 写入 chat_reply_intent_log 失败:', e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据沟通详情(get_chat_detail 的解析结果)判断是否需回复,并用 AI 生成回复文案
|
* 根据沟通详情判断是否需回复,并用 AI 判断意图(文字回复 / 发简历)及生成内容
|
||||||
* 供任务层在「获取详情」指令执行后调用,不包含发送消息(由任务层再下发 send_chat_message 指令)
|
|
||||||
*
|
|
||||||
* @param {object} detail - 沟通详情,含 variant、messages、job 等
|
* @param {object} detail - 沟通详情,含 variant、messages、job 等
|
||||||
* @returns {Promise<object>} { replied: true, reply_content, hr_message_text } | { replied: false, reason }
|
* @param {object} options - 可选,落库用 { sn_code, platform, friendId, encryptFriendId }
|
||||||
|
* @returns {Promise<object>} { replied, action?, reply_content?, hr_message_text?, reason? }
|
||||||
*/
|
*/
|
||||||
async getReplyContentFromDetail(detail) {
|
async getReplyContentFromDetail(detail, options) {
|
||||||
if (!detail || detail.variant !== 'messages' || !Array.isArray(detail.messages) || detail.messages.length === 0) {
|
if (!detail || detail.variant !== 'messages' || !Array.isArray(detail.messages) || detail.messages.length === 0) {
|
||||||
return { replied: false, reason: '无可用消息' };
|
return { replied: false, reason: '无可用消息' };
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages = detail.messages;
|
const messages = detail.messages;
|
||||||
|
|
||||||
// 推断 HR 与 求职者 uid
|
|
||||||
let hr_uid = null;
|
let hr_uid = null;
|
||||||
let geek_uid = null;
|
let geek_uid = null;
|
||||||
|
|
||||||
@@ -217,58 +260,62 @@ class ChatManager {
|
|||||||
const body = msg.body || {};
|
const body = msg.body || {};
|
||||||
const jobDesc = body.jobDesc || body.job_desc || null;
|
const jobDesc = body.jobDesc || body.job_desc || null;
|
||||||
if (jobDesc) {
|
if (jobDesc) {
|
||||||
if (jobDesc.boss && jobDesc.boss.uid && !hr_uid) {
|
if (jobDesc.boss && jobDesc.boss.uid && !hr_uid) hr_uid = jobDesc.boss.uid;
|
||||||
hr_uid = jobDesc.boss.uid;
|
if (jobDesc.geek && jobDesc.geek.uid && !geek_uid) geek_uid = jobDesc.geek.uid;
|
||||||
}
|
|
||||||
if (jobDesc.geek && jobDesc.geek.uid && !geek_uid) {
|
|
||||||
geek_uid = jobDesc.geek.uid;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (hr_uid && geek_uid) break;
|
if (hr_uid && geek_uid) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const last = messages[messages.length - 1];
|
const lastRaw = messages[messages.length - 1];
|
||||||
|
if (lastRaw && lastRaw.from && lastRaw.to) {
|
||||||
// 兜底:还没有 hr_uid 时,用最后一条的 from/to 做简单推断
|
hr_uid = hr_uid || lastRaw.from.uid;
|
||||||
if ((!hr_uid || !geek_uid) && last && last.from && last.to) {
|
geek_uid = geek_uid || lastRaw.to.uid;
|
||||||
hr_uid = hr_uid || last.from.uid;
|
|
||||||
geek_uid = geek_uid || last.to.uid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!last || !last.from || !hr_uid || last.from.uid !== hr_uid) {
|
const jobInfo = detail.job || {};
|
||||||
// 最后一条不是 HR 发的,不自动回复
|
|
||||||
return { replied: false, reason: '最后一条不是HR消息' };
|
const hrList = this._filterHrReplyableMessages(messages, geek_uid);
|
||||||
|
if (hrList.length === 0) {
|
||||||
|
this._saveReplyIntentLog(options, '', jobInfo, '', '', false, '无HR可回复消息(已过滤系统与己方)');
|
||||||
|
return { replied: false, reason: '无HR可回复消息(已过滤系统与己方)' };
|
||||||
|
}
|
||||||
|
|
||||||
|
const last = hrList[hrList.length - 1];
|
||||||
|
if (!last.from || last.from.uid !== hr_uid) {
|
||||||
|
this._saveReplyIntentLog(options, '', jobInfo, '', '', false, '最后一条可回复消息不是HR');
|
||||||
|
return { replied: false, reason: '最后一条可回复消息不是HR' };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取 HR 文本内容(普通文本优先)
|
|
||||||
const body = last.body || {};
|
const body = last.body || {};
|
||||||
const hr_message_text =
|
const hr_message_text =
|
||||||
(typeof body.text === 'string' && body.text) ||
|
(typeof body.text === 'string' && body.text) ||
|
||||||
(typeof last.pushText === 'string' && last.pushText) ||
|
(typeof last.pushText === 'string' && last.pushText) ||
|
||||||
'';
|
'';
|
||||||
|
|
||||||
if (!hr_message_text || !hr_message_text.trim()) {
|
|
||||||
return { replied: false, reason: 'HR消息没有可用文本' };
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 调用阿里云 Qwen 生成回复文案(已在 config 中切换为 qwen-plus)
|
const { action, reply_content } = await ai_service.replyIntentAndContent({
|
||||||
const jobInfo = detail.job || {};
|
|
||||||
|
|
||||||
const reply_content = await ai_service.generateChatContent({
|
|
||||||
jobInfo,
|
jobInfo,
|
||||||
resumeInfo: null,
|
|
||||||
chatType: 'reply',
|
|
||||||
hrMessage: hr_message_text,
|
hrMessage: hr_message_text,
|
||||||
previousMessages: [] // 如需上下文,这里可以把 detail.messages 映射进去
|
previousMessages: hrList.slice(-5).map(m => (m.body && m.body.text) || m.pushText || '')
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!reply_content || !reply_content.trim()) {
|
|
||||||
return { replied: false, reason: 'AI 未生成有效回复' };
|
if (action === 'no_reply') {
|
||||||
|
this._saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, false, 'HR表示暂不匹配/无需回复');
|
||||||
|
return { replied: false, reason: 'HR表示暂不匹配/无需回复' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const needContent = action === 'text';
|
||||||
|
if (needContent && (!reply_content || !reply_content.trim())) {
|
||||||
|
this._saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, false, 'AI 未生成有效回复文案');
|
||||||
|
return { replied: false, reason: 'AI 未生成有效回复文案' };
|
||||||
|
}
|
||||||
|
|
||||||
|
this._saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, true, null);
|
||||||
return {
|
return {
|
||||||
replied: true,
|
replied: true,
|
||||||
reply_content,
|
action: action || 'text',
|
||||||
|
reply_content: reply_content || '',
|
||||||
hr_message_text
|
hr_message_text
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -287,12 +334,25 @@ class ChatManager {
|
|||||||
if (!friendId) throw new Error('friendId 不能为空');
|
if (!friendId) throw new Error('friendId 不能为空');
|
||||||
|
|
||||||
const parsed = await this.get_chat_detail(sn_code, mqttClient, { platform, ...detailParams });
|
const parsed = await this.get_chat_detail(sn_code, mqttClient, { platform, ...detailParams });
|
||||||
const decision = await this.getReplyContentFromDetail(parsed);
|
const decision = await this.getReplyContentFromDetail(parsed, {
|
||||||
|
sn_code,
|
||||||
|
platform,
|
||||||
|
friendId,
|
||||||
|
encryptFriendId: detailParams.encryptFriendId || ''
|
||||||
|
});
|
||||||
if (!decision.replied) return decision;
|
if (!decision.replied) return decision;
|
||||||
|
|
||||||
|
const action = decision.action || 'text';
|
||||||
|
const content = decision.reply_content || '';
|
||||||
|
const actionMessages = {
|
||||||
|
send_resume: [{ type: 'send_resume', content }],
|
||||||
|
exchange_wechat: [{ type: 'exchange_wechat', content }],
|
||||||
|
exchange_phone: [{ type: 'exchange_phone', content }]
|
||||||
|
};
|
||||||
|
const messages = actionMessages[action] || [{ type: 'text', content }];
|
||||||
await this.send_chat_message(sn_code, mqttClient, {
|
await this.send_chat_message(sn_code, mqttClient, {
|
||||||
friendId,
|
friendId,
|
||||||
messages: [{ type: 'text', content: decision.reply_content }],
|
messages,
|
||||||
chatType: 'reply',
|
chatType: 'reply',
|
||||||
platform
|
platform
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -189,16 +189,30 @@ class ChatHandler extends BaseHandler {
|
|||||||
|
|
||||||
await this._saveChatMessagesToDb(parsed, friend, sn_code, platform_type);
|
await this._saveChatMessagesToDb(parsed, friend, sn_code, platform_type);
|
||||||
|
|
||||||
const decision = await chatManager.getReplyContentFromDetail(parsed || {});
|
const decision = await chatManager.getReplyContentFromDetail(parsed || {}, {
|
||||||
|
sn_code,
|
||||||
|
platform: platform_type,
|
||||||
|
friendId: friend_id,
|
||||||
|
encryptFriendId: friend.encryptFriendId || ''
|
||||||
|
});
|
||||||
|
|
||||||
if (decision.replied && decision.reply_content) {
|
if (decision.replied) {
|
||||||
|
const action = decision.action || 'text';
|
||||||
|
const content = decision.reply_content || '';
|
||||||
|
const actionMessages = {
|
||||||
|
send_resume: [{ type: 'send_resume', content }],
|
||||||
|
exchange_wechat: [{ type: 'exchange_wechat', content }],
|
||||||
|
exchange_phone: [{ type: 'exchange_phone', content }]
|
||||||
|
};
|
||||||
|
const messages = actionMessages[action] || [{ type: 'text', content }];
|
||||||
|
const actionNames = { send_resume: '发送简历', exchange_wechat: '换微信', exchange_phone: '换电话' };
|
||||||
const send_command = {
|
const send_command = {
|
||||||
command_type: 'send_chat_message',
|
command_type: 'send_chat_message',
|
||||||
command_name: '发送聊天消息',
|
command_name: actionNames[action] || '发送聊天消息',
|
||||||
command_params: {
|
command_params: {
|
||||||
platform: platform_type,
|
platform: platform_type,
|
||||||
friendId: friend_id,
|
friendId: friend_id,
|
||||||
messages: [{ type: 'text', content: decision.reply_content }],
|
messages,
|
||||||
chatType: 'reply'
|
chatType: 'reply'
|
||||||
},
|
},
|
||||||
priority: config.getTaskPriority('auto_chat') || 6
|
priority: config.getTaskPriority('auto_chat') || 6
|
||||||
|
|||||||
81
api/model/chat_reply_intent_log.js
Normal file
81
api/model/chat_reply_intent_log.js
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
const Sequelize = require('sequelize');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 沟通回复意图 AI 调用记录
|
||||||
|
* 记录 getReplyContentFromDetail 中 replyIntentAndContent 的入参与结果,便于排查与统计
|
||||||
|
*/
|
||||||
|
module.exports = (db) => {
|
||||||
|
const chat_reply_intent_log = db.define('chat_reply_intent_log', {
|
||||||
|
sn_code: {
|
||||||
|
comment: '设备SN码',
|
||||||
|
type: Sequelize.STRING(50),
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: ''
|
||||||
|
},
|
||||||
|
platform: {
|
||||||
|
comment: '平台: boss / liepin',
|
||||||
|
type: Sequelize.STRING(20),
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: 'boss'
|
||||||
|
},
|
||||||
|
friendId: {
|
||||||
|
comment: '好友/会话ID',
|
||||||
|
type: Sequelize.BIGINT,
|
||||||
|
allowNull: true
|
||||||
|
},
|
||||||
|
encrypt_friend_id: {
|
||||||
|
comment: '好友加密ID',
|
||||||
|
type: Sequelize.STRING(100),
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: ''
|
||||||
|
},
|
||||||
|
hr_message_text: {
|
||||||
|
comment: 'HR 最新消息原文(AI 入参)',
|
||||||
|
type: Sequelize.TEXT,
|
||||||
|
allowNull: true
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
comment: 'AI 返回意图: no_reply/text/send_resume/exchange_wechat/exchange_phone',
|
||||||
|
type: Sequelize.STRING(30),
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: ''
|
||||||
|
},
|
||||||
|
reply_content: {
|
||||||
|
comment: 'AI 返回的回复文案',
|
||||||
|
type: Sequelize.TEXT,
|
||||||
|
allowNull: true
|
||||||
|
},
|
||||||
|
replied: {
|
||||||
|
comment: '是否执行了回复',
|
||||||
|
type: Sequelize.BOOLEAN,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: false
|
||||||
|
},
|
||||||
|
reason: {
|
||||||
|
comment: '未回复时的原因',
|
||||||
|
type: Sequelize.STRING(200),
|
||||||
|
allowNull: true
|
||||||
|
},
|
||||||
|
job_name: {
|
||||||
|
comment: '职位名称(便于排查)',
|
||||||
|
type: Sequelize.STRING(200),
|
||||||
|
allowNull: true
|
||||||
|
},
|
||||||
|
create_time: {
|
||||||
|
comment: '创建时间',
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: Sequelize.NOW
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
timestamps: false,
|
||||||
|
indexes: [
|
||||||
|
{ unique: false, fields: ['sn_code', 'platform', 'friendId'] },
|
||||||
|
{ unique: false, fields: ['create_time'] }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// chat_reply_intent_log.sync({ force: true });
|
||||||
|
|
||||||
|
return chat_reply_intent_log;
|
||||||
|
};
|
||||||
@@ -253,6 +253,65 @@ class aiService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 HR 消息判断回复意图并生成内容
|
||||||
|
* @param {object} params - { jobInfo, hrMessage, previousMessages? }
|
||||||
|
* @returns {Promise<{ action: 'text'|'send_resume'|'exchange_wechat'|'exchange_phone', reply_content: string }>}
|
||||||
|
*/
|
||||||
|
async replyIntentAndContent(params) {
|
||||||
|
const { jobInfo = {}, hrMessage = '', previousMessages = [] } = params;
|
||||||
|
const jobName = jobInfo.jobName || jobInfo.title || '未知职位';
|
||||||
|
const companyName = jobInfo.brandName || jobInfo.companyName || '未知公司';
|
||||||
|
|
||||||
|
const prompt = `
|
||||||
|
你正在处理 BOSS 直聘上的求职沟通。根据 HR 最新消息判断求职者应采取的回复动作。
|
||||||
|
|
||||||
|
【职位】${jobName}
|
||||||
|
【公司】${companyName}
|
||||||
|
|
||||||
|
【HR 最新消息】
|
||||||
|
${hrMessage || '(HR 未发文字,仅存在职位卡片等)'}
|
||||||
|
|
||||||
|
请严格按以下 JSON 格式返回(不要包含其他说明或换行):
|
||||||
|
{"action":"动作","reply_content":"内容"}
|
||||||
|
|
||||||
|
action 仅允许以下五种之一:
|
||||||
|
- no_reply:不需要回复(HR 明确表示暂不匹配、感谢关注、有合适机会再沟通、婉拒、不招了等,无需求职者再回复)
|
||||||
|
- text:仅文字回复(普通聊天、打招呼、问是否考虑机会等)
|
||||||
|
- send_resume:发简历(HR 要求发简历、看简历、投递等)
|
||||||
|
- exchange_wechat:换微信(HR 要求加微信、留微信、发微信等)
|
||||||
|
- exchange_phone:换电话(HR 要求留电话、发电话、联系方式等)
|
||||||
|
|
||||||
|
规则:
|
||||||
|
1. 若 HR 明确表示暂不匹配、感谢关注、有合适机会再沟通、与岗位不够匹配、婉拒、不考虑、不招了、已招到 等 → action 为 no_reply,reply_content 留空。
|
||||||
|
2. 若 HR 明确要求发简历/投递/看简历 → action 为 send_resume,reply_content 可为简短附言或空。
|
||||||
|
3. 若 HR 明确要求加微信/留微信/发微信 → action 为 exchange_wechat,reply_content 可为简短附言或空。
|
||||||
|
4. 若 HR 明确要求留电话/发电话/联系方式 → action 为 exchange_phone,reply_content 可为简短附言或空。
|
||||||
|
5. 若仅为普通聊天、打招呼 → action 为 text,reply_content 为一句自然回复(50字以内)。
|
||||||
|
6. reply_content 必须为字符串,不要换行。
|
||||||
|
`.trim();
|
||||||
|
|
||||||
|
const result = await this.callAPI(prompt, {
|
||||||
|
systemPrompt: '你是求职沟通助手。根据 HR 消息判断动作:no_reply(不需要回复)、text(仅文字)、send_resume(发简历)、exchange_wechat(换微信)、exchange_phone(换电话)。HR 婉拒/暂不匹配/感谢关注时用 no_reply。输出 JSON:{"action":"上述五选一","reply_content":"..."}。只返回合法 JSON。',
|
||||||
|
temperature: 0.3,
|
||||||
|
maxTokens: 500,
|
||||||
|
business_type: 'chat_reply_intent',
|
||||||
|
service_type: 'completion'
|
||||||
|
});
|
||||||
|
|
||||||
|
const raw = (result && result.content) ? result.content.trim() : '';
|
||||||
|
const allowed = ['no_reply', 'text', 'send_resume', 'exchange_wechat', 'exchange_phone'];
|
||||||
|
try {
|
||||||
|
const jsonMatch = raw.match(/\{[\s\S]*\}/);
|
||||||
|
const parsed = jsonMatch ? JSON.parse(jsonMatch[0]) : {};
|
||||||
|
const action = allowed.includes(parsed.action) ? parsed.action : 'text';
|
||||||
|
const reply_content = typeof parsed.reply_content === 'string' ? parsed.reply_content.trim() : '';
|
||||||
|
return { action, reply_content };
|
||||||
|
} catch (e) {
|
||||||
|
return { action: 'text', reply_content: raw || '收到,谢谢您。' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分析简历要素
|
* 分析简历要素
|
||||||
* @param {string} resumeText - 简历文本内容
|
* @param {string} resumeText - 简历文本内容
|
||||||
|
|||||||
Reference in New Issue
Block a user