Commit fef41f89 by 朱继来

添加监听、释放脚本

parent 5c9dc96a
package common
import (
"crm-server/internal/dao"
"crm-server/internal/model"
)
// 获取指定任务类型的配置
func GetTaskSetup(task_type int) model.TaskSetup {
var task_setup model.TaskSetup
dao.GetDb().Get(&task_setup, "select * from lie_task_setup where task_type = ?", task_type)
return task_setup
}
// 获取指定任务类型的配置
func GetTaskSetupDetails(task_id int) model.TaskSetupDetails {
var task_setup_details model.TaskSetupDetails
dao.GetDb().Get(&task_setup_details, "select * from lie_task_setup_details where task_id = ?", task_id)
return task_setup_details
}
\ No newline at end of file
package main
// 已成交客户180天未下单释放(提前30天生成任务,截止时间30天)
import (
"crm-server/cmd/task/common"
"crm-server/configs"
"crm-server/internal/dao"
"crm-server/internal/model"
"crm-server/internal/service"
"flag"
"fmt"
"github.com/ichunt2019/logger"
"strconv"
"time"
)
// 日志目录
var LogDir string
// 解析命令行参数
func initArgs() {
flag.StringVar(&LogDir, "logDir", "", "日志目录")
flag.Parse()
}
func main () {
initArgs()
logConfig := make(map[string]string)
logConfig["log_path"] = LogDir+"/task/have_order"
logConfig["log_chan_size"] = "100"
logger.InitLogger("file",logConfig)
logger.Init()
// 查看未下单任务是否开启
task_setup := common.GetTaskSetup(3)
task_setup_details := common.GetTaskSetupDetails(task_setup.Id)
// 定时执行
//task_exec_time, _ := strconv.Atoi(task_setup_details.TsakExecTime)
//ticker := time.NewTicker(time.Minute * time.Duration(task_exec_time))
ticker := time.NewTicker(time.Second * 5)
for {
select {
case <- ticker.C:
fmt.Println("ticker...")
if task_setup.Status == -1 { // 未开启则直接中断
return
}
go setHaveOrderTask(task_setup.Id, task_setup.TaskType, task_setup.TaskDisplayDegree, task_setup_details.TaskEndTime)
default:
time.Sleep(time.Microsecond * 100)
}
}
}
func setHaveOrderTask(task_id, task_type, task_display_degree int, task_end_time int64) {
// 获取未释放且未下单用户
row, err := dao.GetDb().Queryx("select u.user_id, u.copy_ctime from lie_user as u left join lie_user_extend as ue on u.user_id = ue.user_id where " +
"u.is_free = ? and u.is_add_task = ? and ue.no_create_order = ? order by user_id desc limit 1000", 0, 0, 2)
if err != nil {
logger.Info("获取未下单用户失败: ", err.Error())
return
}
for row.Next() {
var user model.Users
row.StructScan(&user)
// 查看用户最后下单时间
var user_extend model.UserExtend
dao.GetDb().Get(&user_extend, "select * from lie_user_extend where user_id = ?", user.User_id)
if user_extend.Latest_Order_Time == 0 {
logger.Info("未获取到最后下单时间,CRM用户ID:%d", user.User_id)
service.DingAlert(configs.Ding_crm_task_token, "任务告警:已成交任务脚本未获取到最后下单时间,CRM用户ID:"+strconv.Itoa(int(user.User_id)), "")
continue
}
current_time := time.Now().Unix() // 当前时间
if (current_time - user_extend.Latest_Order_Time) < 150 * 86400 { // 若距离当前时间小于150天,则跳出循环
continue
}
// 查看用户是否分配
var salesman model.Salesman
dao.GetDb().Get(&salesman, "select * from lie_salesman where user_id = ?", user.User_id)
// 大于150天,则添加到任务信息表
dao.GetDb().Exec("delete from lie_task_info where user_id = ?", user.User_id)
end_time := current_time + task_end_time * 60
dao.GetDb().Exec("insert into lie_task_info (user_id, task_id, task_type, task_display_degree, sale_id, end_time, create_time, update_time) value (?, ?, ?, ?, " +
"?, ?, ?, ?)", user.User_id, task_id, task_type, task_display_degree, salesman.Sale_Id, end_time, current_time, current_time)
dao.GetDb().Exec("update lie_user set is_add_task = ? where user_id = ?", 1, user.User_id)
service.DingAlert(configs.Ding_crm_task_token, "任务告警:已成交任务脚本添加任务记录成功,CRM用户ID:"+strconv.Itoa(int(user.User_id)), "")
}
}
\ No newline at end of file
package main
// 未成交客户30天未下单释放(提前7天生成任务,截止时间7天)
import (
"crm-server/cmd/task/common"
"crm-server/configs"
"crm-server/internal/dao"
"crm-server/internal/model"
"crm-server/internal/service"
"flag"
"fmt"
"github.com/ichunt2019/logger"
"strconv"
"time"
)
// 日志目录
var LogDir string
// 解析命令行参数
func initArgs() {
flag.StringVar(&LogDir, "logDir", "", "日志目录")
flag.Parse()
}
func main () {
initArgs()
logConfig := make(map[string]string)
logConfig["log_path"] = LogDir+"/task/no_order"
logConfig["log_chan_size"] = "100"
logger.InitLogger("file",logConfig)
logger.Init()
// 查看未下单任务是否开启
task_setup := common.GetTaskSetup(2)
task_setup_details := common.GetTaskSetupDetails(task_setup.Id)
// 定时执行
//task_exec_time, _ := strconv.Atoi(task_setup_details.TsakExecTime)
//ticker := time.NewTicker(time.Minute * time.Duration(task_exec_time))
ticker := time.NewTicker(time.Second * 5)
for {
select {
case <- ticker.C:
fmt.Println("ticker...")
if task_setup.Status == -1 { // 未开启则直接中断
return
}
go setNoOrderTask(task_setup.Id, task_setup.TaskType, task_setup.TaskDisplayDegree, task_setup_details.TaskEndTime)
default:
time.Sleep(time.Microsecond * 100)
}
}
}
func setNoOrderTask(task_id, task_type, task_display_degree int, task_end_time int64) {
// 获取未释放且未下单用户
row, err := dao.GetDb().Queryx("select u.user_id, u.copy_ctime from lie_user as u left join lie_user_extend as ue on u.user_id = ue.user_id where " +
"u.is_free = ? u.is_add_task = ? and ue.no_create_order = ? order by user_id desc limit 5", 0, 0, 1)
if err != nil {
logger.Info("获取未下单用户失败: ", err.Error())
return
}
for row.Next() {
var user model.Users
row.StructScan(&user)
// 查看用户是否分配
var salesman model.Salesman
dao.GetDb().Get(&salesman, "select * from lie_salesman where user_id = ?", user.User_id)
var check_time int64 // 校验时间
if salesman.Sale_Id != 0 {
// 转化为int64
s_assign_time := strconv.Itoa(salesman.Assign_Time)
check_time, _ = strconv.ParseInt(s_assign_time,10,64)
} else {
check_time = user.Copy_ctime
}
if check_time == 0 {
logger.Info("未获取到注册或分配时间,CRM用户ID:%d", user.User_id)
service.DingAlert(configs.Ding_crm_task_token, "任务告警:未成交任务脚本未获取到注册或分配时间,CRM用户ID:"+strconv.Itoa(int(user.User_id)), "")
continue
}
current_time := time.Now().Unix() // 当前时间
if (current_time - check_time) < 23 * 86400 { // 若距离当前时间小于23天,则跳出循环
continue
}
// 大于23天,则添加到任务信息表
dao.GetDb().Exec("delete from lie_task_info where user_id = ?", user.User_id)
end_time := current_time + task_end_time * 60
dao.GetDb().Exec("insert into lie_task_info (user_id, task_id, task_type, task_display_degree, sale_id, end_time, create_time, update_time) value (?, ?, ?, ?, " +
"?, ?, ?, ?)", user.User_id, task_id, task_type, task_display_degree, salesman.Sale_Id, end_time, current_time, current_time)
dao.GetDb().Exec("update lie_user set is_add_task = ? where user_id = ?", 1, user.User_id)
service.DingAlert(configs.Ding_crm_task_token, "任务告警:未成交任务脚本添加任务记录成功,CRM用户ID:"+strconv.Itoa(int(user.User_id)), "")
}
}
\ No newline at end of file
package main
// 监听待处理的任务记录,截止时间小于等于当前时间则标记为已超时,并释放或自动分配
import (
"crm-server/configs"
"crm-server/internal/dao"
"crm-server/internal/model"
"crm-server/internal/service"
"flag"
"fmt"
"github.com/ichunt2019/logger"
"math/rand"
"strconv"
"strings"
"time"
)
// CMS user_info
type UserInfo struct {
UserId int `db:"userId"`
}
// CMS user_department
type UserDepartment struct {
DepartmentId int `db:"department_id"`
DepartmentName string `db:"department_name"`
ParentId int `db:"parent_id"`
}
// 日志目录
var LogDir string
// 解析命令行参数
func initArgs() {
flag.StringVar(&LogDir, "logDir", "", "日志目录")
flag.Parse()
}
func main() {
initArgs()
logConfig := make(map[string]string)
logConfig["log_path"] = LogDir + "/task/taskMonitor"
logConfig["log_chan_size"] = "100"
logger.InitLogger("file", logConfig)
logger.Init()
// 定时执行
ticker := time.NewTicker(time.Second * 5)
for {
select {
case <-ticker.C:
fmt.Println("ticker...")
go updateOverTime()
default:
time.Sleep(time.Microsecond * 100)
}
}
}
func updateOverTime() {
row, err := dao.GetDb().Queryx("select * from lie_task_info where status = 1")
if err != nil {
logger.Info("获取待处理的任务记录失败: ", err.Error())
return
}
for row.Next() {
var task_info model.TaskInfo
row.StructScan(&task_info)
var current_time = time.Now().Unix()
// 若截止时间为0 或 大于当前时间,则跳出本次循环,不处理
if task_info.EndTime == 0 || task_info.EndTime > current_time {
continue
}
// 获取任务配置详情
var task_setup_details model.TaskSetupDetails
err = dao.GetDb().Get(&task_setup_details, "select * from lie_task_setup_details where task_id = ?", task_info.TaskId)
if err != nil {
logger.Info("获取任务配置详情失败,任务Id:%d,错误原因:%v", task_info.TaskId, err.Error())
service.DingAlert(configs.Ding_crm_task_token, "任务告警:任务脚本获取任务配置详情失败,CRM用户ID:"+strconv.Itoa(task_info.UserId)+",任务ID:"+strconv.Itoa(task_info.TaskId)+",原因:"+err.Error(), "")
continue
}
// 设置上一任客服
var salesman model.Salesman
dao.GetDb().Get(&salesman, "select sale_id from lie_salesman where user_id = ?", task_info.UserId)
if salesman.Sale_Id != 0 {
dao.GetDb().Exec("update lie_user set last_sale_id = ? where user_id = ?", salesman.Sale_Id, task_info.UserId)
}
// TaskResult: 1-释放客户至公共池,2-重新分配客服
if task_setup_details.TaskResult == 1 {
dao.GetDb().Exec("update lie_user set is_free = ?, free_time = ?, is_churn = ? where user_id = ?", 1, current_time, 0, task_info.UserId)
dao.GetDb().Exec("delete from lie_salesman where user_id = ?", task_info.UserId)
dao.GetDb().Exec("insert into lie_action_log (user_id, type, event, remark, create_time) values (?, ?, ?, ?, ?)", task_info.UserId, 2, "释放用户", "", current_time)
service.DingAlert(configs.Ding_crm_task_token, "任务告警:任务脚本释放用户成功,CRM用户ID:"+strconv.Itoa(task_info.UserId), "")
} else {
// 获取adtag、ptag
var user model.Users
dao.GetDb().Get(&user, "select user_id,outter_uid,adtag,ptag from lie_user where user_id = ?", task_info.UserId)
if user.Adtag != "" || user.Ptag != "" {
// 获取自动分配表指定的客服
var sale_tag model.SaleTag
dao.GetDb().Get(&sale_tag, "select sale_id from lie_sale_tag where adtag = ? or ptag = ?", user.Adtag, user.Ptag)
var sale_id int
var msg_txt string
if sale_tag.SaleId != 0 { // 自动分配
sale_id = sale_tag.SaleId
msg_txt = "任务脚本自动分配客服"
} else { // 随机取一个客服
user_info := RandomSelctSales()
sale_id = user_info.UserId
msg_txt = "任务脚本随机分配客服"
}
dao.GetDb().Exec("update lie_salesman set sale_id = ?, create_time = ?, update_time = ? where user_id = ?", sale_id, current_time, current_time, task_info.UserId)
service.DingAlert(configs.Ding_crm_task_token, "任务告警:"+msg_txt+"成功,CRM用户ID:"+strconv.Itoa(task_info.UserId)+",指定客服ID:"+strconv.Itoa(sale_id), "")
}
}
// 标记已超时状态
dao.GetDb().Exec("update lie_task_info set status = ? where id = ?", -1, task_info.Id)
}
return
}
// 随机选择一个线上客服
func RandomSelctSales() *UserInfo {
online_sales_department_ids := GetOnlineSaleDepartment()
params := make([]interface{}, 0)
for i := 0; i < len(online_sales_department_ids); i++ {
params = append(params, online_sales_department_ids[i])
}
var user_info []*UserInfo
query := fmt.Sprintf("select userId from user_info where department_id in (%s)", placeholders(len(online_sales_department_ids)))
dao.GetCmsDb().Select(&user_info, query, params...)
random := getRandom(len(user_info))
return user_info[random]
}
// 拼接占位符
func placeholders(n int) string {
var b strings.Builder
for i := 0; i < n-1; i++ {
b.WriteString("?,")
}
if n > 0 {
b.WriteString("?")
}
return b.String()
}
// 获取随机数
func getRandom(len int) int {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
return r.Intn(len)
}
// 获取线上销售所有部门 (线上销售部 33)
func GetOnlineSaleDepartment() []int {
var online_sales_department_ids []int
online_sales_department_ids = append(online_sales_department_ids, 33)
var user_department []*UserDepartment
dao.GetCmsDb().Select(&user_department, "select department_id,department_name,parent_id from user_department where parent_id = 33")
for _, v := range user_department {
online_sales_department_ids = append(online_sales_department_ids, v.DepartmentId)
}
return online_sales_department_ids
}
package model
type SaleTag struct {
Id int `json:"id" db:"id"`
SaleId int `json:"sale_id" db:"sale_id"`
SaleName string `json:"sale_name" db:"sale_name"`
Adtag string `json:"adtag" db:"adtag"`
Ptag string `json:"ptag" db:"ptag"`
CreateTime int64 `json:"create_time" db:"create_time"`
IsDel int `json:"is_del" db:"is_del"`
}
package model
type Salesman struct {
Id int `json:"id" db:"id"`
User_Id int `json:"user_id" db:"user_id"`
Sale_Id int `json:"sale_id" db:"sale_id"`
Assign_Time int `json:"assign_time" db:"assign_time"`
Update_Time int `json:"update_time" db:"update_time"`
SysLimit int `json:"sys_limit" db:"sys_limit"`
LimitFollowTime int `json:"limit_follow_time" db:"limit_follow_time"`
Id int `json:"id" db:"id"`
User_Id int `json:"user_id" db:"user_id"`
Sale_Id int `json:"sale_id" db:"sale_id"`
Assign_Time int `json:"assign_time" db:"assign_time"`
Update_Time int `json:"update_time" db:"update_time"`
SysLimit int `json:"sys_limit" db:"sys_limit"`
LimitFollowTime int `json:"limit_follow_time" db:"limit_follow_time"`
}
/*
CREATE TABLE `lie_salesman` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
......@@ -21,4 +19,4 @@ CREATE TABLE `lie_salesman` (
`update_time` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=69 DEFAULT CHARSET=utf8;
*/
\ No newline at end of file
*/
package model
type TaskInfo struct {
Id int `json:"id" db:"id"`
UserId int `json:"user_id" db:"user_id"`
TaskId int `json:"task_id" db:"task_id"`
TaskType int `json:"task_type" db:"task_type"`
TaskDisplayDegree int `json:"task_display_degree" db:"task_display_degree"`
SaleId int `json:"sale_id" db:"sale_id"`
Status int `json:"status" db:"status"`
EndTime int64 `json:"end_time" db:"end_time"`
CreateTime int64 `json:"create_time" db:"create_time"`
UpdateTime int64 `json:"update_time" db:"update_time"`
}
package model
type TaskSetup struct {
Id int `json:"id" db:"id"`
TaskType int `json:"task_type" db:"task_type"`
TaskDisplayDegree int `json:"task_display_degree" db:"task_display_degree"`
Remark string `json:"remark" db:"remark"`
Status int `json:"status" db:"status"`
CreateTime int64 `json:"create_time" db:"create_time"`
UpdateTime int64 `json:"update_time" db:"update_time"`
}
package model
type TaskSetupDetails struct {
Id int `json:"id" db:"id"`
TaskId int `json:"task_id" db:"task_id"`
TaskExecTimeType int `json:"task_exec_time_type" db:"task_exec_time_type"`
TsakExecTime string `json:"task_exec_time" db:"task_exec_time"`
TaskEndTime int64 `json:"task_end_time" db:"task_end_time"`
TaskResult int `json:"task_result" db:"task_result"`
RuleRemark string `json:"rule_remark" db:"rule_remark"`
CreateTime int64 `json:"create_time" db:"create_time"`
UpdateTime int64 `json:"update_time" db:"update_time"`
}
package model
type UserExtend struct {
Id int `db:"id"`
User_Id int `db:"user_id"`
Outter_Uid int `db:"outter_uid"`
No_Create_Order int `db:"no_create_order"`
Latest_Order_Time int `db:"latest_order_time"`
Completed_Order_Nums int `db:"completed_order_nums"`
Model_Nums int `db:"model_nums"`
Total_Order_Amount float64 `db:"total_order_amount"`
Amount_Paid float64 `db:"amount_paid"`
Contact string `db:"contact"`
Contact_Info string `db:"contact_info"`
Create_Time int `db:"create_time"`
Id int `db:"id"`
User_Id int `db:"user_id"`
Outter_Uid int `db:"outter_uid"`
No_Create_Order int `db:"no_create_order"`
Latest_Order_Time int64 `db:"latest_order_time"`
Completed_Order_Nums int `db:"completed_order_nums"`
Model_Nums int `db:"model_nums"`
Total_Order_Amount float64 `db:"total_order_amount"`
Amount_Paid float64 `db:"amount_paid"`
Contact string `db:"contact"`
Contact_Info string `db:"contact_info"`
Create_Time int64 `db:"create_time"`
}
......@@ -2,9 +2,41 @@ package model
// Kratos hello kratos.
type Users struct {
User_id int64 `json:"user_id" db:"user_id"`
Outter_uid int64 `json:"outter_uid" db:"outter_uid"`
Is_free int64 `json:"is_free" db:"is_free"`
Free_time int64 `json:"free_time" db:"free_time"`
Is_churn int64 `json:"is_churn" db:"is_churn"`
}
\ No newline at end of file
User_id int64 `json:"user_id" db:"user_id"`
Outter_uid int64 `json:"outter_uid" db:"outter_uid"`
Source string `json:"source" db:"source"`
Adtag string `json:"adtag" db:"adtag"`
Jd_account string `json:"jd_account" db:"jd_account"`
Mobile string `json:"mobile" db:"mobile"`
Email string `json:"email" db:"email"`
Name string `json:"name" db:"name"`
Wechat string `json:"wechat" db:"wechat"`
QQ string `json:"qq" db:"qq"`
Grade int64 `json:"grade" db:"grade"`
Status int64 `json:"status" db:"status"`
Channel_source int64 `json:"channel_source" db:"channel_source"`
Channel_source_other string `json:"channel_source_other" db:"channel_source_other"`
Channel_about_us string `json:"channel_about_us" db:"channel_about_us"`
Need_type int64 `json:"need_type" db:"need_type"`
Need_type_other string `json:"need_type_other" db:"need_type_other"`
Customer_identity int64 `json:"customer_identity" db:"customer_identity"`
Customer_identity_other string `json:"customer_identity_other" db:"customer_identity_other"`
Is_add_wechat int64 `json:"is_add_wechat" db:"is_add_wechat"`
Is_join_group int64 `json:"is_join_group" db:"is_join_group"`
Is_competing_goods int64 `json:"is_competing_goods" db:"is_competing_goods"`
Follow_up_situation string `json:"follow_up_situation" db:"follow_up_situation"`
Remark string `json:"remark" db:"remark"`
Create_time int64 `json:"create_time" db:"create_time"`
Update_time int64 `json:"update_time" db:"update_time"`
Copy_ctime int64 `json:"copy_ctime" db:"copy_ctime"`
Is_potential_cus int64 `json:"is_potential_cus" db:"is_potential_cus"`
Fkid int64 `json:"fkid" db:"fkid"`
Ptag string `json:"ptag" db:"ptag"`
Is_value int64 `json:"is_value" db:"is_value"`
Last_sale_id int64 `json:"last_sale_id" db:"last_sale_id"`
Reason string `json:"reason" db:"reason"`
Is_show int64 `json:"is_show" db:"is_show"`
Is_free int64 `json:"is_free" db:"is_free"`
Free_time int64 `json:"free_time" db:"free_time"`
Is_churn int64 `json:"is_churn" db:"is_churn"`
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment