jobutil.go 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065
  1. package main
  2. import (
  3. "app.yhyue.com/moapp/jybase/mail"
  4. "app.yhyue.com/moapp/jybase/redis"
  5. "database/sql"
  6. "fmt"
  7. "github.com/tealeg/xlsx"
  8. "log"
  9. "math"
  10. "strings"
  11. "time"
  12. "github.com/gogf/gf/v2/util/gconv"
  13. "app.yhyue.com/moapp/jybase/common"
  14. "app.yhyue.com/moapp/jybase/date"
  15. "app.yhyue.com/moapp/jybase/mongodb"
  16. )
  17. // 电销工单生成
  18. func rderAcceptance() {
  19. sql := fmt.Sprintf(`select * from order_acceptance where is_clue=2 and is_delete=1 order by propose_time `)
  20. //sql := fmt.Sprintf(`select * from order_acceptance where is_clue=2 and is_delete=1 and id = 333 order by propose_time `)
  21. data := WorkOrder.SelectBySql(sql)
  22. if data != nil && len(*data) > 0 {
  23. for _, v := range *data {
  24. acceptance_no := gconv.String(v["acceptance_no"])
  25. childrenArr := WorkOrder.Find("order_acceptance_children", map[string]interface{}{
  26. "acceptance_no": acceptance_no,
  27. }, "", "", -1, -1)
  28. if childrenArr != nil && len(*childrenArr) > 0 {
  29. company := ""
  30. phone := ""
  31. demand := ""
  32. name := ""
  33. product := ""
  34. for _, v1 := range *childrenArr {
  35. if gconv.String(v1["field_name"]) == "公司名称" {
  36. company = gconv.String(v1["field_value"])
  37. }
  38. if gconv.String(v1["field_name"]) == "联系方式num" {
  39. phone = gconv.String(v1["field_value"])
  40. }
  41. if gconv.String(v1["field_name"]) == "客户姓名" {
  42. name = gconv.String(v1["field_value"])
  43. }
  44. if gconv.String(v1["field_name"]) == "客户需求" {
  45. demand = gconv.String(v1["field_value"])
  46. }
  47. if gconv.String(v1["field_name"]) == "咨询产品" {
  48. product = gconv.String(v1["field_value"])
  49. }
  50. }
  51. //工单开始创建
  52. if !WorkDataHandle(company, phone, demand, name, product, v) {
  53. log.Println("工单创建失败")
  54. }
  55. }
  56. }
  57. }
  58. }
  59. // 工单创建处理
  60. func WorkDataHandle(company, phone, demand, name, product string, acceptanceData map[string]interface{}) bool {
  61. uId := ""
  62. query := map[string]interface{}{}
  63. contactsData := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where phone = ? and is_delete = 1", phone)
  64. if contactsData != nil && len(*contactsData) > 0 {
  65. if common.ObjToString((*contactsData)[0]["baseinfo_id"]) != "" {
  66. uId = common.ObjToString((*contactsData)[0]["baseinfo_id"])
  67. query["uid"] = uId
  68. }
  69. }
  70. if uId == "" {
  71. log.Println("用户信息不存在")
  72. return false
  73. }
  74. cluename := company
  75. if cluename == "" {
  76. cluename = phone //没有线索名,手机号代替
  77. }
  78. ok, data, saleData := false, map[string]interface{}{}, []map[string]interface{}{}
  79. isGroup, isCommerce := GetCompanyType(cluename, uId)
  80. uCount, _ := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", ""), true //查当前线索是否已存在
  81. if uCount != nil && len(*uCount) > 0 {
  82. //线索信息修改
  83. isUpdate := gconv.Int64((*uCount)["is_artificially_modified"])
  84. if isUpdate == 1 {
  85. cluename = ""
  86. }
  87. clueId := gconv.Int64((*uCount)["id"])
  88. positionId := gconv.Int64((*uCount)["position_id"])
  89. lockPositionId := gconv.Int64((*uCount)["lock_position_id"])
  90. trailstatus := gconv.String((*uCount)["trailstatus"])
  91. IS_TRANSFER := gconv.Int64((*uCount)["IS_TRANSFER"])
  92. //1客成0销售
  93. if IS_TRANSFER == 1 {
  94. //客成处理
  95. //客成
  96. //生成客成数据
  97. customerMap := TiDb.FindOne("dwd_f_csm_customer_info", map[string]interface{}{
  98. "clue_id": clueId,
  99. }, "position_id,name", "")
  100. if customerMap != nil && len(*customerMap) > 0 {
  101. WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String((*uCount)["name"]), phone, "", "", "", "", "", "", gconv.String((*uCount)["seat_number"]), "", gconv.Int64((*uCount)["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand)
  102. data = map[string]interface{}{
  103. "type": "kc",
  104. "position_id": (*customerMap)["position_id"],
  105. "name": (*customerMap)["name"],
  106. }
  107. } else {
  108. log.Println("查询不到客成数据", clueId, uId)
  109. return false
  110. }
  111. AddChangeRecord(nil, clueId, gconv.Int64((*customerMap)["position_id"]), "", "加入任务车", "咨询客服转客成", "", time.Now().Format(date.Date_Full_Layout), "", -1)
  112. } else {
  113. //普通销售
  114. if positionId == 0 && lockPositionId == 0 {
  115. //线索变更
  116. ok, data, saleData = FindPosition(0, "", gconv.String(acceptanceData["creator_time"]))
  117. if !ok {
  118. log.Println(positionId, "用户查询失败")
  119. return false
  120. }
  121. WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), "", gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, true, demand)
  122. } else {
  123. ok, data, saleData := true, map[string]interface{}{}, []map[string]interface{}{}
  124. if positionId == 0 {
  125. ok, data, saleData = FindPosition(lockPositionId, trailstatus, gconv.String(acceptanceData["creator_time"]))
  126. } else {
  127. ok, data, saleData = FindPosition(positionId, trailstatus, gconv.String(acceptanceData["creator_time"]))
  128. }
  129. if !ok {
  130. log.Println(positionId, "用户查询失败")
  131. return false
  132. }
  133. if gconv.Int64(data["position_id"]) == positionId {
  134. WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), "", gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand)
  135. } else {
  136. WorkUpdateClue(*uCount, saleData, "", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), "", gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, true, demand)
  137. }
  138. }
  139. }
  140. } else {
  141. //新增线索
  142. relatedId, _, _ := FindRelatedClueData(cluename, isGroup, isCommerce)
  143. ok, data, _ = FindPosition(relatedId, "", gconv.String(acceptanceData["creator_time"]))
  144. if !ok {
  145. return false
  146. }
  147. SaveClue("", "", uId, "5", "169", "新增线索", "主动咨询客服留资客户", cluename, name, gconv.String(data["name"]), phone, "", "", "", "", "", "", gconv.String(data["seat_number"]), gconv.Int64(data["position_id"]), "", "", "", []string{}, "", isGroup, isCommerce, false, demand)
  148. }
  149. //工单生成
  150. ok1 := AddOrderWork(acceptanceData, data, product, phone, company)
  151. log.Println("工单创建", ok1, gconv.String(acceptanceData["acceptance_no"]))
  152. return true
  153. }
  154. func AddOrderWork(acceptanceData map[string]interface{}, userData map[string]interface{}, product, phone, company string) bool {
  155. nowTime := time.Now().Format(date.Date_Full_Layout)
  156. work_order_no := fmt.Sprintf("GD%s%s", time.Now().Format(date.Date_yyyyMMdd), FindNumber("gd"))
  157. productArr := []string{}
  158. for _, v := range strings.Split(product, ",") {
  159. switch ProductMap[v] {
  160. case "dk":
  161. continue
  162. default:
  163. productArr = append(productArr, v)
  164. }
  165. }
  166. two_type := "dx"
  167. if gconv.String(userData["type"]) == "kc" {
  168. two_type = "kc"
  169. }
  170. personMap := GetPerson(gconv.String(userData["position_id"]))
  171. if personMap == nil || len(personMap) == 0 {
  172. return false
  173. }
  174. orderWorkMap := map[string]interface{}{
  175. "work_order_no": work_order_no,
  176. "acceptance_no": gconv.String(acceptanceData["acceptance_no"]),
  177. "type": strings.Join(productArr, ","),
  178. "status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, 1),
  179. "initiator_name": gconv.String(acceptanceData["creator_name"]),
  180. "initiator_position_id": gconv.String(acceptanceData["initiator_position_id"]),
  181. "current_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, nil, userData["name"]),
  182. "current_position_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, nil, userData["position_id"]),
  183. "history_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["name"], nil),
  184. "history_postion_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["position_id"], nil),
  185. "is_delete": 1,
  186. "creator_name": gconv.String(acceptanceData["creator_name"]),
  187. "creator_position_id": gconv.String(acceptanceData["creator_position_id"]),
  188. "creator_time": nowTime,
  189. "two_type": two_type,
  190. "department_no": gconv.String(personMap["deptId"]),
  191. "department_name": gconv.String(personMap["deptName"]),
  192. "update_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil),
  193. }
  194. ok3 := WorkOrder.Insert("order_work", orderWorkMap)
  195. if ok3 > 0 {
  196. status := 2
  197. if WorkOrder.Count("order_work", map[string]interface{}{
  198. "status": 1,
  199. "acceptance_no": gconv.String(acceptanceData["acceptance_no"]),
  200. }) > 0 {
  201. status = 1
  202. }
  203. WorkOrder.Update("order_acceptance", map[string]interface{}{
  204. "id": acceptanceData["id"],
  205. }, map[string]interface{}{
  206. "is_clue": 3,
  207. "status": status,
  208. "over_time": common.If(status == 1, nil, nowTime),
  209. })
  210. //日志添加
  211. approvalRecordMap := map[string]interface{}{
  212. "work_order_no": work_order_no,
  213. "status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 3, 1),
  214. "new_status": common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, nil),
  215. "handle_name": userData["name"],
  216. "handle_position_id": userData["position_id"],
  217. "handle_dept_id": gconv.String(personMap["deptId"]),
  218. "handle_dept_name": gconv.String(personMap["deptName"]),
  219. "creator_name": gconv.String(acceptanceData["creator_name"]),
  220. "creator_position_id": gconv.String(acceptanceData["initiator_position_id"]),
  221. "is_delete": 1,
  222. "creator_time": nowTime,
  223. "handle_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil),
  224. "update_name": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["name"], nil),
  225. "update_position_id": common.If(gconv.Int64(userData["orderStatus"]) == 0, userData["position_id"], nil),
  226. "update_time": common.If(gconv.Int64(userData["orderStatus"]) == 0, nowTime, nil),
  227. }
  228. WorkOrder.Insert("approval_record", approvalRecordMap)
  229. WorkMail(personMap,
  230. strings.Join(productArr, ","),
  231. gconv.Int64(common.If(gconv.Int64(userData["orderStatus"]) == 0, 2, 1)),
  232. gconv.String(personMap["name"]),
  233. gconv.String(acceptanceData["creator_name"]),
  234. nowTime,
  235. work_order_no,
  236. phone,
  237. company)
  238. return true
  239. }
  240. return false
  241. }
  242. // 本级以及上级管理员查询
  243. func GetPerson(positionId string) map[string]interface{} {
  244. person := map[string]interface{}{}
  245. positionArrMap := Base.SelectBySql(fmt.Sprintf(`select a.phone,b.id,b.ent_id from
  246. base_user a
  247. INNER JOIN base_position b
  248. on b.id=%s and b.user_id=a.id and b.type=1`,
  249. positionId))
  250. if positionArrMap == nil || len(*positionArrMap) == 0 {
  251. return map[string]interface{}{}
  252. }
  253. phone := gconv.String((*positionArrMap)[0]["phone"])
  254. entId := gconv.String((*positionArrMap)[0]["ent_id"])
  255. entUserArrMap := Mysql.SelectBySql(fmt.Sprintf(`SELECT
  256. a.name as name,a.mail as mail,b.dept_id as deptId,a.phone ,c.name as deptName
  257. FROM
  258. entniche_user a
  259. INNER JOIN entniche_department_user b ON a.ent_id =%s
  260. AND a.phone IN %s
  261. and a.id=b.user_id
  262. inner join entniche_department c on b.dept_id=c.id
  263. `, entId, fmt.Sprintf("(%s)", phone)))
  264. //商机管理员
  265. if entUserArrMap == nil || len(*entUserArrMap) == 0 {
  266. return map[string]interface{}{}
  267. }
  268. deptId := gconv.Int64((*entUserArrMap)[0]["deptId"])
  269. person = map[string]interface{}{
  270. "name": gconv.String((*entUserArrMap)[0]["name"]),
  271. "mail": gconv.String((*entUserArrMap)[0]["mail"]),
  272. "phone": gconv.String((*entUserArrMap)[0]["phone"]),
  273. "deptId": gconv.String((*entUserArrMap)[0]["deptId"]),
  274. "deptName": gconv.String((*entUserArrMap)[0]["deptName"]),
  275. }
  276. //本部门管理员查询
  277. depthMap := Mysql.SelectBySql(`SELECT
  278. c.name as name,c.mail as mail
  279. FROM
  280. entniche_department_user a
  281. INNER JOIN entniche_user_role b ON a.dept_id = ?
  282. AND a.user_id = b.user_id
  283. AND b.role_id !=""
  284. INNER JOIN entniche_user c ON a.user_id = c.id`, deptId)
  285. if depthMap != nil && len(*depthMap) > 0 {
  286. person["deptPersonName"] = gconv.String((*depthMap)[0]["name"])
  287. person["deptPersonMail"] = gconv.String((*depthMap)[0]["mail"])
  288. }
  289. //商机管理员查询
  290. superiorDepthMap := Mysql.SelectBySql(`SELECT
  291. c.*
  292. FROM
  293. entniche_department d
  294. INNER JOIN entniche_department_user a ON d.id = ?
  295. AND d.pid = a.dept_id
  296. INNER JOIN entniche_user_role b ON a.user_id = b.user_id
  297. AND b.role_id !=""
  298. INNER JOIN entniche_user c ON a.user_id = c.id`, deptId)
  299. if superiorDepthMap != nil && len(*superiorDepthMap) > 0 {
  300. person["superiorDepthPersonName"] = gconv.String((*superiorDepthMap)[0]["name"])
  301. person["superiorDepthPersonMail"] = gconv.String((*superiorDepthMap)[0]["mail"])
  302. }
  303. return person
  304. }
  305. // 编号查询
  306. func FindNumber(moudle string) string {
  307. today := time.Now().Format("2006-01-02")
  308. yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
  309. key := fmt.Sprintf("%s_%s", today, moudle)
  310. yesterdayKey := fmt.Sprintf("%s_%s", yesterday, moudle)
  311. if ok, _ := redis.Exists("newother", yesterdayKey); ok {
  312. //删除之前数据
  313. redis.Del("newother", yesterdayKey)
  314. }
  315. count := redis.Incr("newother", key)
  316. log.Println("编号获取", moudle, fmt.Sprintf("%04d", count))
  317. return fmt.Sprintf("%04d", count)
  318. }
  319. // 人员查询
  320. func GetAllocation(proportion1, proportion3 float64, deptCount1, deptCount3 int64, administrators1, administrators3 map[string]interface{}, creatorTime string) map[string]interface{} {
  321. log.Println("分配比例查询", proportion1, proportion3, deptCount1, deptCount3)
  322. if deptCount1 == 0 {
  323. return administrators1
  324. }
  325. if deptCount3 == 0 {
  326. return administrators3
  327. }
  328. nowAllocationRatio := math.Round(gconv.Float64(deptCount1 / deptCount3))
  329. if cfg.AllocationRatio == 0 {
  330. //重新计算
  331. cfg.AllocationRatio = math.Round(proportion1 / proportion3)
  332. cfg.AllocationTime = creatorTime
  333. common.WriteSysConfig(&cfg)
  334. log.Println("新增计算比例", cfg.AllocationRatio)
  335. return administrators1
  336. } else {
  337. if nowAllocationRatio == cfg.AllocationRatio {
  338. //重新计算
  339. cfg.AllocationRatio = math.Round(proportion1 / proportion3)
  340. cfg.AllocationTime = creatorTime
  341. common.WriteSysConfig(&cfg)
  342. return administrators1
  343. }
  344. }
  345. if nowAllocationRatio > cfg.AllocationRatio {
  346. return administrators3
  347. } else {
  348. return administrators1
  349. }
  350. //达到比例也重新计算
  351. }
  352. func FindPosition(positionId int64, trailstatus, creatorTime string) (bool, map[string]interface{}, []map[string]interface{}) {
  353. allData := []map[string]interface{}{}
  354. //查询两个部门高级管理员
  355. //查询两个部门所有人员标识
  356. //电销三部
  357. userData1 := TiDb.SelectBySql(`SELECT
  358. a.position_id,
  359. a.name,
  360. b.seat_number,
  361. b.role_id,
  362. a.bi_pcode,
  363. a.dept_name
  364. FROM
  365. dwd_d_crm_department_level_succbi a
  366. INNER JOIN dwd_f_crm_personnel_management b ON a.resign = 0 and b.resign = 0
  367. AND a.dept_name LIKE "销售一部%"
  368. AND a.position_id = b.position_id`)
  369. userData3 := TiDb.SelectBySql(`SELECT
  370. a.position_id,
  371. a.name,
  372. b.seat_number,
  373. b.role_id,
  374. a.bi_pcode,
  375. a.dept_name
  376. FROM
  377. dwd_d_crm_department_level_succbi a
  378. INNER JOIN dwd_f_crm_personnel_management b ON a.resign = 0 and b.resign = 0
  379. AND a.resign = 0
  380. AND a.dept_name LIKE "%销售三部"
  381. AND a.position_id = b.position_id`)
  382. if userData3 == nil || len(*userData3) == 0 || userData1 == nil || len(*userData1) == 0 {
  383. return false, map[string]interface{}{}, allData
  384. }
  385. //一部管理员信息
  386. administrators1 := map[string]interface{}{}
  387. //三部管理员信息
  388. administrators3 := map[string]interface{}{}
  389. //返回当前人信息
  390. administrators := map[string]interface{}{}
  391. //电销一部
  392. deptNameMap1 := map[string]interface{}{}
  393. deptNameMap3 := map[string]interface{}{}
  394. proportion1 := float64(0)
  395. proportion3 := float64(0)
  396. for _, v := range *userData3 {
  397. v["type"] = 3
  398. id := gconv.Int64(v["position_id"])
  399. roleId := gconv.Int64(v["role_id"])
  400. if id == positionId {
  401. administrators = v
  402. }
  403. if roleId == 8 {
  404. v["orderStatus"] = 2
  405. administrators3 = v
  406. } else if roleId == 3 {
  407. proportion3 += 0.5
  408. } else {
  409. proportion3 += 1
  410. }
  411. deptNameMap3[gconv.String(v["bi_pcode"])] = true
  412. allData = append(allData, v)
  413. }
  414. for _, v := range *userData1 {
  415. v["type"] = 1
  416. id := gconv.Int64(v["position_id"])
  417. roleId := gconv.Int64(v["role_id"])
  418. if id == positionId {
  419. administrators = v
  420. }
  421. if roleId == 8 {
  422. v["orderStatus"] = 2
  423. administrators1 = v
  424. } else if roleId == 3 {
  425. proportion1 += 0.5
  426. } else {
  427. proportion1 += 1
  428. }
  429. deptNameMap1[gconv.String(v["bi_pcode"])] = true
  430. allData = append(allData, v)
  431. }
  432. if positionId != 0 {
  433. if administrators == nil || len(administrators) == 0 {
  434. return false, map[string]interface{}{}, allData
  435. }
  436. positiontype := gconv.Int64(administrators["type"])
  437. if trailstatus == "01" {
  438. switch positiontype {
  439. case 1:
  440. //找他上级
  441. administrators = administrators1
  442. case 3:
  443. //找他上级
  444. administrators = administrators3
  445. }
  446. return true, administrators, allData
  447. } else {
  448. return true, administrators, allData
  449. }
  450. }
  451. //按照比例分配选择一部还是三部
  452. //一部查询
  453. deptCount1 := CalculateProportion(deptNameMap1)
  454. //三部查询
  455. deptCount3 := CalculateProportion(deptNameMap3)
  456. return true, GetAllocation(proportion1, proportion3, deptCount1, deptCount3, administrators1, administrators3, creatorTime), allData
  457. log.Println("电销信息获取失败", positionId)
  458. return false, map[string]interface{}{}, allData
  459. }
  460. func CalculateProportion(deptNameMap map[string]interface{}) int64 {
  461. deptNameStr := ""
  462. for k := range deptNameMap {
  463. if deptNameStr == "" {
  464. deptNameStr = k
  465. } else {
  466. deptNameStr = fmt.Sprintf("%s,%s", deptNameStr, k)
  467. }
  468. }
  469. if deptNameStr == "" {
  470. return int64(0)
  471. }
  472. count := int64(0)
  473. sql := fmt.Sprintf(`SELECT
  474. sum(1) as count
  475. FROM
  476. order_work a
  477. INNER JOIN approval_record b ON a.creator_time >= "%s"
  478. AND FIND_IN_SET( a.department_no , "%s")
  479. AND a.work_order_no = b.work_order_no
  480. and (b.new_status!= 1 or b.new_status is null )
  481. `, cfg.AllocationTime, deptNameStr)
  482. data := WorkOrder.SelectBySql(sql)
  483. if data != nil && len(*data) > 0 {
  484. count = gconv.Int64((*data)[0]["count"])
  485. }
  486. return count
  487. }
  488. // 未支付订单 30分钟一次
  489. func orders() {
  490. //一个小时未支付进入线索 A
  491. log.Println("未支付订单定时任务开始")
  492. lastOrderId := cfg.LastOrderId
  493. selectTimeStart := time.Unix(time.Now().Unix()-7200, 0).Format(date.Date_Full_Layout)
  494. selectTimeEnd := time.Unix(time.Now().Unix()-3600, 0).Format(date.Date_Full_Layout)
  495. sql := fmt.Sprintf(`select * from dataexport_order where create_time <= "%s" and create_time >= "%s" and id > %s`, selectTimeEnd, selectTimeStart, fmt.Sprint(lastOrderId))
  496. //sql := fmt.Sprintf(`select * from dataexport_order where id=260265`)
  497. data := Mysql.SelectBySql(sql)
  498. if data != nil && *data != nil && len(*data) > 0 {
  499. for _, v := range *data {
  500. order_status := common.IntAll(v["order_status"])
  501. is_backstage_order := common.IntAll(v["is_backstage_order"])
  502. product_type_str1 := `"大会员","VIP订阅","数据流量包","历史数据"`
  503. product_type := common.ObjToString(v["product_type"])
  504. if order_status == 0 && is_backstage_order == 0 && strings.Contains(product_type_str1, product_type) {
  505. ok1, ok2, _ := FormatData(v, "orders")
  506. if !ok1 {
  507. common.WriteSysConfig(&cfg)
  508. log.Println("线索卡点", "orders", v, selectTimeEnd, selectTimeStart)
  509. } else {
  510. if !ok2 {
  511. log.Println("用户分配已达上限", "orders", v, selectTimeEnd, selectTimeStart)
  512. common.WriteSysConfig(&cfg)
  513. }
  514. }
  515. }
  516. cfg.LastOrderId = common.IntAll(v["id"])
  517. }
  518. }
  519. common.WriteSysConfig(&cfg)
  520. log.Println("未支付订单定时任务结束")
  521. }
  522. func readClue() {
  523. log.Println("读表进线索定时任务开始")
  524. lastReadClueTime := cfg.LastReadClueTime
  525. sql := fmt.Sprintf(`select * from clue_info where updatetime > "%s" order by updatetime asc`, fmt.Sprint(lastReadClueTime))
  526. data := TiDb.SelectBySql(sql)
  527. if data != nil && *data != nil && len(*data) > 0 {
  528. for _, v := range *data {
  529. ok1, ok2, _ := FormatData(v, "readClue")
  530. if !ok1 {
  531. common.WriteSysConfig(&cfg)
  532. log.Println("线索卡点", "readClue", v, lastReadClueTime)
  533. } else {
  534. if !ok2 {
  535. log.Println("用户分配已达上限", "readClue", v, lastReadClueTime)
  536. common.WriteSysConfig(&cfg)
  537. }
  538. }
  539. cfg.LastReadClueTime = common.ObjToString(v["updatetime"])
  540. }
  541. }
  542. common.WriteSysConfig(&cfg)
  543. log.Println("读表进线索定时任务结束")
  544. }
  545. // 新注册用户 5分钟一次
  546. func users() {
  547. //判断节假日
  548. runOk := getRunOk()
  549. if !runOk {
  550. log.Println("不是工作日,任务暂停")
  551. return
  552. }
  553. //新用户注册后5分钟内进入线索 C
  554. log.Println("新注册用户定时任务开始")
  555. selectTimeEnd := cfg.LastUserId
  556. sql := fmt.Sprintf(`select * from dwd_f_userbase_baseinfo where createtime > "%s" and (s_platform != 'xcx' or s_platform is NULL) and source = "0101" and status != 2 order by createtime asc`, selectTimeEnd)
  557. data := TiDb.SelectBySql(sql)
  558. abhList := []map[string]interface{}{}
  559. if data != nil && *data != nil && len(*data) > 0 {
  560. for k, v := range *data {
  561. //判断用户是否有小程序切使用过剑鱼其他产品
  562. createtime := common.ObjToString(v["createtime"])
  563. ok1, ok2, ok3 := FormatData(v, "users")
  564. if !ok3 {
  565. cfg.LastUserId = createtime
  566. //安博会数据
  567. abhList = append(abhList, v)
  568. continue
  569. }
  570. if !ok1 {
  571. log.Println("线索卡点", "users", v, selectTimeEnd)
  572. } else {
  573. if !ok2 {
  574. log.Println("用户分配已达上限", "users", v, selectTimeEnd)
  575. }
  576. }
  577. if k == len(*data)-1 {
  578. cfg.LastUserId = createtime
  579. }
  580. }
  581. if len(abhList) > 0 {
  582. //安博会发邮件高翔
  583. ABHEmail("user", abhList)
  584. }
  585. }
  586. common.WriteSysConfig(&cfg)
  587. selectXcxTimeEnd := cfg.LastXcxUserId
  588. xcxSql := fmt.Sprintf(`SELECT DISTINCT
  589. aa.mgo_id as userId,
  590. cc.code as industry ,
  591. aa.phone,
  592. IF
  593. ( aa.phone_time IS NULL, aa.create_time, aa.phone_time ) as time
  594. FROM
  595. debris_product.miniprogram_user aa
  596. INNER JOIN debris_product.miniprogram bb ON (
  597. aa.phone <> ''
  598. AND
  599. IF
  600. ( aa.phone_time IS NULL, aa.create_time, aa.phone_time ) > '%s'
  601. AND aa.miniprogram_code = bb.CODE
  602. )
  603. INNER JOIN debris_product.industry cc ON ( bb.industry_code = cc.CODE )
  604. WHERE
  605. NOT EXISTS (
  606. SELECT
  607. 1
  608. FROM
  609. debris_product.miniprogram_user a
  610. INNER JOIN debris_product.miniprogram b ON (
  611. aa.unionid = a.unionid
  612. AND aa.miniprogram_code = a.miniprogram_code
  613. AND aa.id != a.id
  614. AND
  615. IF
  616. ( a.phone_time IS NULL, a.create_time, a.phone_time ) <= '%s'
  617. AND a.miniprogram_code = b.CODE
  618. )
  619. INNER JOIN debris_product.miniprogram_user c ON ( a.unionid = c.unionid AND b.CODE = c.miniprogram_code ))
  620. ORDER BY time
  621. `, selectXcxTimeEnd, selectXcxTimeEnd)
  622. xcxData := debrisProductMysql.SelectBySql(xcxSql)
  623. log.Println("11122", selectXcxTimeEnd, xcxData)
  624. if xcxData != nil && *xcxData != nil && len(*xcxData) > 0 {
  625. afList := []map[string]interface{}{}
  626. for k, v := range *xcxData {
  627. //判断用户是否有小程序切使用过剑鱼其他产品
  628. //判断uid
  629. uId := ""
  630. for i := 0; i < 10; i++ {
  631. phone := common.ObjToString(v["phone"])
  632. contactsData := TiDb.SelectBySql("select * from dwd_f_userbase_contacts where phone = ? and is_delete = 1", phone)
  633. if contactsData != nil && len(*contactsData) > 0 {
  634. if common.ObjToString((*contactsData)[0]["baseinfo_id"]) != "" {
  635. uId = common.ObjToString((*contactsData)[0]["baseinfo_id"])
  636. }
  637. }
  638. if uId == "" {
  639. time.Sleep(1 * time.Minute)
  640. } else {
  641. break
  642. }
  643. }
  644. updatetime := common.ObjToString(v["time"])
  645. if uId == "" {
  646. cfg.LastXcxUserId = updatetime
  647. continue
  648. }
  649. ok1, ok2, _ := FormatData(v, "xcxusers")
  650. /*if !ok3 {
  651. //首次使用"安防"小程序新注册用户
  652. afList = append(afList, v)
  653. cfg.LastXcxUserId = updatetime
  654. continue
  655. }*/
  656. if !ok1 {
  657. common.WriteSysConfig(&cfg)
  658. log.Println("小程序用户分配线索卡点", "xcxusers", v, selectXcxTimeEnd)
  659. } else {
  660. if !ok2 {
  661. log.Println("小程序用户分配已达上限", "xcxusers", v, selectXcxTimeEnd)
  662. common.WriteSysConfig(&cfg)
  663. }
  664. }
  665. if k == len(*xcxData)-1 {
  666. cfg.LastXcxUserId = updatetime
  667. }
  668. }
  669. if len(afList) > 0 {
  670. //发邮件给张文福
  671. AFEmail(afList)
  672. }
  673. }
  674. common.WriteSysConfig(&cfg)
  675. log.Println("新注册用户定时任务结束")
  676. }
  677. // 留资 5分钟一次
  678. func saleLeads() {
  679. //判断节假日
  680. runOk := getRunOk()
  681. if !runOk {
  682. log.Println("不是工作日,任务暂停")
  683. return
  684. }
  685. //留资后5分钟内进入线索
  686. //分为免费留资和付费留资 付费B 免费C
  687. log.Println("用户留资定时任务开始")
  688. session := Mgo.GetMgoConn()
  689. lastId := cfg.LastId
  690. abhList := []map[string]interface{}{}
  691. defer func() {
  692. Mgo.DestoryMongoConn(session)
  693. }()
  694. query := map[string]interface{}{}
  695. if lastId != "" {
  696. query["_id"] = map[string]interface{}{"$gt": mongodb.StringTOBsonId(lastId)}
  697. }
  698. log.Println("query :", query)
  699. iter := session.DB(db.Mgo.DbName).C("saleLeads").Find(&query).Sort("_id").Iter()
  700. thisData := map[string]interface{}{}
  701. for {
  702. if !iter.Next(&thisData) {
  703. break
  704. }
  705. sourceCode := common.ObjToString(thisData["source"])
  706. if sourceCode == "" {
  707. log.Println("留资没有source", thisData)
  708. continue
  709. }
  710. //
  711. filterArr := []string{"-pc", "-app", "-wx", "-h5"}
  712. sourceMap := map[string]string{}
  713. saleSource := TiDb.SelectBySql(`SELECT source,name FROM d_saleleads_code WHERE (department LIKE '%大客户%' or department LIKE '%市场组%' or department LIKE '%咨询组%' or department LIKE '%运营部%') AND is_delete = 1`)
  714. if saleSource != nil && len(*saleSource) > 0 {
  715. for _, v := range *saleSource {
  716. source := common.ObjToString(v["source"])
  717. name := common.ObjToString(v["name"])
  718. for _, s := range filterArr {
  719. name = strings.ReplaceAll(name, s, "")
  720. }
  721. sourceMap[source] = name
  722. }
  723. }
  724. if sourceMap[sourceCode] != "" {
  725. continue
  726. }
  727. ok1, ok2, ok3 := FormatData(thisData, "saleLeads")
  728. if !ok3 {
  729. cfg.LastId = mongodb.BsonIdToSId(thisData["_id"])
  730. //安博会数据
  731. abhList = append(abhList, thisData)
  732. continue
  733. }
  734. if !ok1 {
  735. log.Println("线索卡点", "saleLeads", thisData, lastId)
  736. } else {
  737. if !ok2 {
  738. log.Println("用户分配已达上限", "saleLeads", thisData, lastId)
  739. }
  740. }
  741. cfg.LastId = mongodb.BsonIdToSId(thisData["_id"])
  742. }
  743. if len(abhList) > 0 {
  744. //安博会发邮件高翔
  745. ABHEmail("saleLeads", abhList)
  746. }
  747. common.WriteSysConfig(&cfg)
  748. log.Println("用户留资定时任务结束")
  749. }
  750. func userbase() {
  751. log.Println("userbase定时任务开始")
  752. timeUnix := time.Now().Unix()
  753. selectTimeStart := time.Unix(timeUnix-1800, 0).Format("2006-01-02 15:04:05")
  754. selectTimeEnd := time.Unix(timeUnix, 0).Format("2006-01-02 15:04:05")
  755. sql := fmt.Sprintf(`SELECT
  756. a.phone,b.uid,a.baseinfo_id,b.l_registedate,a.createtime,b.id,b.userid
  757. FROM
  758. dwd_f_userbase_contacts a
  759. INNER JOIN dwd_f_userbase_baseinfo b ON
  760. b.status= 1
  761. and (b.s_platform != 'xcx' or b.s_platform is NULL)
  762. AND a.phone = b.phone and a.baseinfo_id= b.uid and a.source ="0101"
  763. and a.phone is not NULL
  764. and a.createtime >="%s"
  765. and a.createtime <"%s"
  766. and a.is_delete=1
  767. ORDER BY a.createtime `, selectTimeStart, selectTimeEnd)
  768. data := TiDb.SelectBySql(sql)
  769. if data != nil && *data != nil && len(*data) > 0 {
  770. for _, v := range *data {
  771. phone := common.ObjToString(v["phone"])
  772. uId := common.ObjToString(v["uid"])
  773. userId := common.ObjToString(v["userid"])
  774. registedate := common.ObjToString(v["l_registedate"])
  775. name := common.ObjToString(v["name"])
  776. nowTime := time.Now().Format(date.Date_Full_Layout)
  777. layout := "2006-01-02 15:04:05"
  778. createtime := gconv.String(v["createtime"])
  779. createtimeInt64, _ := time.Parse(layout, createtime)
  780. registedateInt64, _ := time.Parse(layout, registedate)
  781. count := TiDb.CountBySql("select count(1) as count from dwd_f_crm_clue_info where uid = ?", uId)
  782. if createtimeInt64.Unix()-registedateInt64.Unix() < int64(db.RegTimes)*86400 {
  783. if count == 0 {
  784. //注册少于7天、走新增
  785. data := TiDb.FindOne("dwd_f_userbase_baseinfo", map[string]interface{}{
  786. "id": gconv.Int64(v["id"]),
  787. }, "", "")
  788. if data != nil && len(*data) > 0 {
  789. ok1, ok2, _ := FormatData(v, "users")
  790. if !ok1 {
  791. log.Println("线索卡点", "userbase uid", v, uId)
  792. } else {
  793. if !ok2 {
  794. log.Println("用户分配已达上限", "userbase uid", v, uId)
  795. }
  796. }
  797. }
  798. }
  799. continue
  800. }
  801. registedates, _ := time.Parse(date.Date_Full_Layout, registedate)
  802. log.Println("userbase uid 线索数量 ", count)
  803. log.Println("userbase uid 注册时间 ", registedates)
  804. if count == 0 {
  805. clueId := int64(0)
  806. sql := fmt.Sprintf(`select * from freeClubSign where mogUserId="%s" and sub_again_date > "%s" `, userId, selectTimeEnd)
  807. data := BiService.SelectBySql(sql)
  808. if len(*data) > 0 && userId != "" {
  809. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  810. "userid": userId,
  811. "uid": uId,
  812. "is_assign": 0,
  813. "comeintime": nowTime,
  814. "createtime": nowTime,
  815. "updatetime": nowTime,
  816. "cluename": phone,
  817. "top_cluetype": "532",
  818. "sub_cluetype": "670",
  819. "trailstatus": "01",
  820. "name": name,
  821. "phone": phone,
  822. "comeintime_open": nowTime,
  823. "comeinsource_open": 1,
  824. "FREEZE_TIME": nowTime,
  825. })
  826. } else {
  827. clueId = TiDb.Insert("dwd_f_crm_clue_info", map[string]interface{}{
  828. "userid": userId,
  829. "uid": uId,
  830. "is_assign": 0,
  831. "comeintime": nowTime,
  832. "createtime": nowTime,
  833. "updatetime": nowTime,
  834. "cluename": phone,
  835. "top_cluetype": "532",
  836. "sub_cluetype": "475",
  837. "trailstatus": "01",
  838. "name": name,
  839. "phone": phone,
  840. "comeintime_open": nowTime,
  841. "comeinsource_open": 1,
  842. "FREEZE_TIME": nowTime,
  843. })
  844. }
  845. if clueId > 0 {
  846. AddChangeRecord(nil, clueId, -1, "", "创建线索", "系统自动创建", "/", nowTime, "", -1)
  847. }
  848. }
  849. }
  850. }
  851. log.Println("userbase定时任务结束")
  852. }
  853. func getRunOk() bool {
  854. currentTime, runOk := time.Now(), false
  855. if currentTime.Weekday() == time.Sunday {
  856. isok := false
  857. for k, v := range DateMap {
  858. if currentTime.Format(date.Date_Short_Layout) == k && v == 2 {
  859. isok = true
  860. }
  861. }
  862. if isok {
  863. runOk = true
  864. }
  865. } else {
  866. isok := true
  867. for k, v := range DateMap {
  868. if currentTime.Format(date.Date_Short_Layout) == k && v == 1 {
  869. isok = false
  870. }
  871. }
  872. if isok {
  873. runOk = true
  874. }
  875. }
  876. return runOk
  877. }
  878. func getAreaCode(userId string) (code string) {
  879. followData := Base.Find("follow_project_monitor", map[string]interface{}{"s_userid": userId}, "", "", -1, -1)
  880. sidArr := []string{}
  881. if followData != nil && len(*followData) > 0 {
  882. for _, v := range *followData {
  883. infoId := common.ObjToString(v["s_id"])
  884. sidArr = append(sidArr, infoId)
  885. }
  886. }
  887. if len(sidArr) > 0 {
  888. query := `{"query": {"bool": {"must": [{"terms": {"_id": ["%s"]}}],"must_not": [],"should": []}}}`
  889. query = fmt.Sprintf(query, strings.Join(sidArr, `","`))
  890. biddingData := Es.Get("bidding", "bidding", query)
  891. if biddingData != nil && len(*biddingData) > 0 {
  892. codeMap := map[string]string{}
  893. codeArr := []string{}
  894. for _, v := range *biddingData {
  895. area := common.ObjToString(v["area"])
  896. address := common.ObjToString(v["city"])
  897. if address == "" {
  898. address = area
  899. }
  900. codeMap[address] = AreaCode[address]
  901. }
  902. if len(codeMap) > 0 {
  903. for _, v := range codeMap {
  904. codeArr = append(codeArr, v)
  905. }
  906. }
  907. if len(codeArr) > 0 {
  908. code = strings.Join(codeArr, ",")
  909. }
  910. }
  911. }
  912. log.Println("code ", code)
  913. return
  914. }
  915. func getClueType(item string, data map[string]interface{}, sourceCode string, sourceId int64) (pcode, code, level, topname, subname string) {
  916. if item == "orders" {
  917. productType := common.ObjToString(data["product_type"])
  918. pcode = "1"
  919. level = "A"
  920. topname = "提交订单未支付"
  921. if productType == "VIP订阅" {
  922. code = "6"
  923. subname = "超级订阅"
  924. } else if productType == "大会员" {
  925. code = "7"
  926. subname = "大会员"
  927. } else if productType == "数据流量包" {
  928. code = "8"
  929. subname = "数据流量包"
  930. } else if productType == "历史数据" {
  931. code = "9"
  932. subname = "数据自助导出"
  933. }
  934. } else if item == "users" {
  935. pcode = "4"
  936. code = "154"
  937. level = "C"
  938. topname = "新增注册"
  939. subname = "新增注册用户"
  940. } else if item == "message" {
  941. pcode = "532"
  942. code = "477"
  943. level = "B"
  944. topname = "其他"
  945. subname = "机器人客服主动咨询"
  946. } else if item == "readClue" {
  947. level = "A"
  948. topname = "超级订阅临期用户"
  949. pcode = "614"
  950. if sourceId == 1 {
  951. code = "615"
  952. subname = "60天后到期"
  953. } else if sourceId == 2 {
  954. code = "616"
  955. subname = "45天后到期"
  956. } else if sourceId == 3 {
  957. code = "617"
  958. subname = "15天后到期"
  959. } else {
  960. code = "618"
  961. subname = "7天后到期"
  962. }
  963. } else if item == "allocation" {
  964. pcode = "532"
  965. code = "671"
  966. level = "D"
  967. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  968. if pcodeData != nil && len(*pcodeData) > 0 {
  969. topname = common.ObjToString((*pcodeData)["name"])
  970. }
  971. pcodeData = TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": code}, "", "")
  972. if pcodeData != nil && len(*pcodeData) > 0 {
  973. subname = common.ObjToString((*pcodeData)["name"])
  974. }
  975. } else if item == "rebind" {
  976. pcode = "532"
  977. code = "670"
  978. level = "D"
  979. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  980. if pcodeData != nil && len(*pcodeData) > 0 {
  981. topname = common.ObjToString((*pcodeData)["name"])
  982. }
  983. pcodeData = TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": code}, "", "")
  984. if pcodeData != nil && len(*pcodeData) > 0 {
  985. subname = common.ObjToString((*pcodeData)["name"])
  986. }
  987. } else if item == "invite" {
  988. codeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": sourceCode}, "", "")
  989. if codeData != nil && len(*codeData) > 0 {
  990. pcode = common.ObjToString((*codeData)["pcode"])
  991. code = common.ObjToString((*codeData)["code"])
  992. level = common.ObjToString((*codeData)["clue_level"])
  993. subname = common.ObjToString((*codeData)["name"])
  994. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  995. if pcodeData != nil && len(*pcodeData) > 0 {
  996. topname = common.ObjToString((*pcodeData)["name"])
  997. }
  998. }
  999. } else {
  1000. if sourceCode != "" {
  1001. codeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"source": sourceCode}, "", "")
  1002. if codeData != nil && len(*codeData) > 0 {
  1003. pcode = common.ObjToString((*codeData)["pcode"])
  1004. code = common.ObjToString((*codeData)["code"])
  1005. level = common.ObjToString((*codeData)["clue_level"])
  1006. subname = common.ObjToString((*codeData)["name"])
  1007. pcodeData := TiDb.FindOne("dwd_d_crm_cluetype_code", map[string]interface{}{"code": pcode}, "", "")
  1008. if pcodeData != nil && len(*pcodeData) > 0 {
  1009. topname = common.ObjToString((*pcodeData)["name"])
  1010. }
  1011. }
  1012. }
  1013. }
  1014. return
  1015. }
  1016. // 获取自动分配的人
  1017. func autoDraw(mode, cluename, phone string, isGroup, isCommerce int) (positionId int64, seatNumber, saleName string, saleData []map[string]interface{}, isOk, isFreeze bool, noticePositionId int64) {
  1018. isOk = false
  1019. isFreeze = false
  1020. pdata := TiDb.SelectBySql(`select * from dwd_f_crm_personnel_management where seat_number is not null and seat_number != ""`)
  1021. if pdata == nil {
  1022. positionId = 0
  1023. seatNumber = ""
  1024. saleName = ""
  1025. return
  1026. }
  1027. saleData = *pdata
  1028. if TiDb.Count("dwd_f_crm_clue_info", map[string]interface{}{"phone": phone, "is_assign": 1}) == 0 { //线索没销售进入,有销售走分配次数最少的逻辑
  1029. //线索不存在
  1030. if isGroup == 0 && isCommerce == 1 && cluename != "" { //非集团在工商库线索名不为空
  1031. companyList := FindRelatedData(cluename, isGroup, isCommerce)
  1032. paramArr := []string{}
  1033. companyArr := []interface{}{}
  1034. if len(companyList) > 0 {
  1035. for _, v := range companyList {
  1036. paramArr = append(paramArr, "?")
  1037. companyArr = append(companyArr, v)
  1038. }
  1039. }
  1040. clueClueStr := fmt.Sprintf("select position_id,is_assign from dwd_f_crm_clue_info where cluename in (%s) order by id ", strings.Join(paramArr, ","))
  1041. cdata := TiDb.SelectBySql(clueClueStr, companyArr...)
  1042. if cdata != nil && len(*cdata) > 0 { //找到关联公司所有信息
  1043. isOk = true
  1044. lockPositionId := int64(0)
  1045. for _, v := range *cdata {
  1046. isAssign := gconv.Int64(v["is_assign"])
  1047. if isAssign == 1 {
  1048. //已经分配过
  1049. if gconv.Int64(v["position_id"]) > 0 {
  1050. positionId = gconv.Int64(v["position_id"])
  1051. seatNumber = gconv.String(v["seatNumber"])
  1052. }
  1053. } else {
  1054. lockPositionId = gconv.Int64(v["lock_position_id"])
  1055. }
  1056. }
  1057. if positionId == 0 && lockPositionId > 0 {
  1058. positionId = lockPositionId
  1059. for _, v := range *pdata {
  1060. if lockPositionId == gconv.Int64(v["position_id"]) {
  1061. seatNumber = gconv.String(v["seat_number"])
  1062. }
  1063. }
  1064. }
  1065. if FindUpperLimit(gconv.String(positionId), mode, true) {
  1066. isFreeze = true
  1067. positionId = 0
  1068. seatNumber = ""
  1069. saleName = ""
  1070. } else {
  1071. for _, v := range *pdata {
  1072. if positionId == common.Int64All(v["position_id"]) {
  1073. seatNumber = common.ObjToString(v["seat_number"])
  1074. saleName = common.ObjToString(v["name"])
  1075. }
  1076. }
  1077. return
  1078. }
  1079. }
  1080. }
  1081. }
  1082. positionId = 0
  1083. seatNumber = ""
  1084. saleName = ""
  1085. query := `select * from dwd_f_crm_personnel_management where assign_type = 1 and`
  1086. if mode == "A" {
  1087. query += ` assign_level like "%A%"`
  1088. } else if mode == "B" {
  1089. query += ` assign_level like "%B%"`
  1090. } else if mode == "D" {
  1091. query += ` assign_level like "%D%"`
  1092. } else if mode == "C" {
  1093. query += ` assign_level like "%C%"`
  1094. } else if mode == "S" {
  1095. query += ` assign_level like "%S%"`
  1096. }
  1097. data := TiDb.SelectBySql(query)
  1098. if data != nil && len(*data) > 0 {
  1099. saleData = *data
  1100. sql := "select * from dwd_f_crm_clue_autodraw_record where clue_level = ?"
  1101. countData := TiDb.SelectBySql(sql, mode)
  1102. if countData != nil && len(*countData) > 0 {
  1103. for _, v := range *data {
  1104. isOk := false //判断是否有新员工
  1105. for _, vv := range *countData {
  1106. if common.Int64All(v["position_id"]) == common.Int64All(vv["position_id"]) {
  1107. if common.IntAll(v["resign"]) == 0 {
  1108. vv["status"] = 1
  1109. } else {
  1110. vv["status"] = 2
  1111. }
  1112. isOk = true
  1113. }
  1114. }
  1115. if !isOk { //有新员工直接分给新员工
  1116. positionId = common.Int64All(v["position_id"])
  1117. saleName = common.ObjToString(v["name"])
  1118. log.Println("新员工, ", positionId, saleName)
  1119. rData := TiDb.FindOne("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"clue_level": mode}, "", "count desc")
  1120. TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
  1121. "position_id": positionId,
  1122. "clue_level": mode,
  1123. "count": common.Int64All((*rData)["count"]),
  1124. })
  1125. break
  1126. }
  1127. }
  1128. if positionId == 0 {
  1129. res := int64(0)
  1130. countres := 0
  1131. for _, v := range *countData {
  1132. if common.IntAll(v["status"]) == 1 {
  1133. if FindUpperLimit(gconv.String(v["position_id"]), mode, false) {
  1134. continue
  1135. }
  1136. if countres == 0 {
  1137. res = common.Int64All(v["count"])
  1138. positionId = common.Int64All(v["position_id"])
  1139. } else {
  1140. if common.Int64All(v["count"]) <= res {
  1141. res = common.Int64All(v["count"])
  1142. positionId = common.Int64All(v["position_id"])
  1143. }
  1144. }
  1145. countres++
  1146. }
  1147. }
  1148. log.Println(444, res)
  1149. }
  1150. } else {
  1151. for _, kv := range *data {
  1152. positionId1 := gconv.String(kv["position_id"])
  1153. if !FindUpperLimit(positionId1, "", false) {
  1154. positionId = common.Int64All(kv["position_id"])
  1155. saleName = common.ObjToString(kv["name"])
  1156. rData := TiDb.FindOne("dwd_f_crm_clue_autodraw_record", map[string]interface{}{"clue_level": mode}, "", "count desc")
  1157. if rData != nil && len(*rData) > 0 {
  1158. TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
  1159. "position_id": positionId,
  1160. "clue_level": mode,
  1161. "count": common.Int64All((*rData)["count"]),
  1162. })
  1163. } else {
  1164. TiDb.Insert("dwd_f_crm_clue_autodraw_record", map[string]interface{}{
  1165. "position_id": positionId,
  1166. "clue_level": mode,
  1167. "count": 0,
  1168. })
  1169. }
  1170. break
  1171. }
  1172. }
  1173. }
  1174. for _, v := range *data {
  1175. if positionId == common.Int64All(v["position_id"]) {
  1176. seatNumber = common.ObjToString(v["seat_number"])
  1177. saleName = common.ObjToString(v["name"])
  1178. }
  1179. }
  1180. }
  1181. return
  1182. }
  1183. func getPositionId(phone string) (positionId int64) {
  1184. userData, ok := Mgo.FindOne("user", map[string]interface{}{"s_phone": phone})
  1185. if ok && userData != nil && len(*userData) > 0 {
  1186. userId := common.Int64All((*userData)["base_user_id"])
  1187. positionData := Base.FindOne("base_position", map[string]interface{}{"type": 1, "ent_id": db.EntId, "user_id": userId}, "", "") //TODO ent_id
  1188. if positionData != nil && len(*positionData) > 0 {
  1189. positionId = common.Int64All((*positionData)["id"])
  1190. }
  1191. }
  1192. return
  1193. }
  1194. func GetCompanyType(companyName string, uId string) (int, int) {
  1195. isGroup, isCommerce := 0, 0
  1196. uCount := TiDb.FindOne("dwd_f_crm_clue_info", map[string]interface{}{"uid": uId}, "", "")
  1197. if uCount != nil && len(*uCount) > 0 {
  1198. isUpdate := gconv.Int64((*uCount)["is_artificially_modified"])
  1199. if isUpdate == 1 {
  1200. companyName = gconv.String((*uCount)["cluename"])
  1201. }
  1202. if companyName == "" {
  1203. companyName = gconv.String((*uCount)["cluename"])
  1204. }
  1205. }
  1206. if companyName == "" {
  1207. return isGroup, isCommerce
  1208. }
  1209. //是否是集团
  1210. if c := TiDb.CountBySql(`select count(1) from group_company_name where company_name=?`, companyName); c > 0 {
  1211. isGroup = 1
  1212. }
  1213. //是否在工商库
  1214. if companyName != "" {
  1215. if c := MgoQyxy.Count("qyxy_std", map[string]interface{}{"company_name": companyName, "company_type": map[string]interface{}{"$ne": "个体工商户"}}); c > 0 {
  1216. isCommerce = 1
  1217. }
  1218. }
  1219. return isGroup, isCommerce
  1220. }
  1221. // 查询是否达上限
  1222. func FindUpperLimit(positionId string, level string, isAdd bool) bool {
  1223. if positionId == "" {
  1224. return false
  1225. }
  1226. isFull := TiDb.CountBySql(`select count(1) from dwd_f_crm_clue_info where position_id=? and is_assign=1 and is_transfer != 1 `, positionId) >= db.AllocationCap
  1227. if isFull && isAdd && level != "" {
  1228. TiDb.UpdateOrDeleteBySql(`update dwd_f_crm_clue_autodraw_record set count = count + 1 where position_id = ? and clue_level = ?`, positionId, level)
  1229. }
  1230. return isFull
  1231. }
  1232. func getSeatNumberPositionId(seatNumber string) (positionId int64) {
  1233. saleData := TiDb.FindOne("dwd_f_crm_personnel_management", map[string]interface{}{"seat_number": seatNumber}, "", "")
  1234. if saleData != nil && len(*saleData) > 0 {
  1235. positionId = common.Int64All((*saleData)["position_id"])
  1236. }
  1237. return
  1238. }
  1239. // 重新关注用户处理
  1240. func rebind() {
  1241. log.Println("重新关注用户处理开始")
  1242. //判断节假日
  1243. runOk := getRunOk()
  1244. if !runOk {
  1245. log.Println("不是工作日,任务暂停")
  1246. return
  1247. }
  1248. rebindTimeEnd := cfg.RebindTime
  1249. sql := fmt.Sprintf(`select * from freeClubSign where sub_again_date > "%s" order by sub_again_date asc`, rebindTimeEnd)
  1250. data := BiService.SelectBySql(sql)
  1251. if data != nil && *data != nil && len(*data) > 0 {
  1252. for _, v := range *data {
  1253. rebindTimeEnd = common.ObjToString(v["sub_again_date"])
  1254. registedates, _ := time.Parse(date.Date_Full_Layout, gconv.String(v["register_time"]))
  1255. if time.Now().Unix()-registedates.Unix() > int64(db.RegTimes)*86400 {
  1256. ok1, ok2, _ := FormatData(v, "rebind")
  1257. if !ok1 {
  1258. log.Println("线索卡点", "allocation", v, rebindTimeEnd)
  1259. } else {
  1260. if !ok2 {
  1261. log.Println("用户分配已达上限", "allocation", v, rebindTimeEnd)
  1262. }
  1263. }
  1264. }
  1265. }
  1266. cfg.RebindTime = rebindTimeEnd
  1267. common.WriteSysConfig(&cfg)
  1268. }
  1269. log.Println("重新关注用户处理结束")
  1270. }
  1271. // 活跃用户处理
  1272. func activeUsers() {
  1273. log.Println("活跃用户处理开始")
  1274. //判断节假日
  1275. runOk := getRunOk()
  1276. if !runOk {
  1277. log.Println("不是工作日,任务暂停")
  1278. return
  1279. }
  1280. //活跃用户查询
  1281. activeTimeEnd := cfg.ActiveTime
  1282. sql := fmt.Sprintf(`select * from freeClubSign where act_again_date > "%s" order by act_again_date asc`, activeTimeEnd)
  1283. data := BiService.SelectBySql(sql)
  1284. if data != nil && *data != nil && len(*data) > 0 {
  1285. for _, v := range *data {
  1286. activeTimeEnd = common.ObjToString(v["act_again_date"])
  1287. ok1, ok2, _ := FormatData(v, "allocation")
  1288. log.Println(v, "allocation", ok1, ok2)
  1289. if !ok1 {
  1290. log.Println("线索卡点", "allocation", v, activeTimeEnd)
  1291. } else {
  1292. if !ok2 {
  1293. log.Println("用户分配已达上限", "allocation", v, activeTimeEnd)
  1294. }
  1295. }
  1296. }
  1297. cfg.ActiveTime = activeTimeEnd
  1298. common.WriteSysConfig(&cfg)
  1299. }
  1300. log.Println("活跃用户处理结束")
  1301. }
  1302. // 安博会邮件
  1303. /*func ABHEmail(source string, data []map[string]interface{}) {
  1304. fileName, detailName, email, dir := "", "", "", ""
  1305. var err error
  1306. switch source {
  1307. case "user":
  1308. xlsxArr := []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"}
  1309. batch := FindBatch("abh")
  1310. fileName, detailName = "安博会用户注册销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, ""
  1311. xf := xlsx.NewFile()
  1312. style := xlsx.NewStyle()
  1313. style.Font.Size = 12
  1314. style.Font.Bold = true
  1315. style.Alignment.Vertical = "center"
  1316. style.Alignment.Horizontal = "center"
  1317. detailName = "今日新增安博会销售线索,请查收附件,及时跟进。"
  1318. sh, _ := xf.AddSheet("线索数据")
  1319. row1 := sh.AddRow()
  1320. for _, x := range xlsxArr {
  1321. cell := row1.AddCell()
  1322. cell.SetString(x)
  1323. cell.SetStyle(style)
  1324. }
  1325. for _, v := range data {
  1326. row := sh.AddRow()
  1327. row.AddCell().SetString(common.ObjToString(v["name"]))
  1328. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1329. row.AddCell().SetString(common.ObjToString(v["email"]))
  1330. row.AddCell().SetString(common.ObjToString(v["company_name"]))
  1331. row.AddCell().SetString("")
  1332. row.AddCell().SetString("")
  1333. row.AddCell().SetString("安博会用户注册")
  1334. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  1335. //增加客户需求
  1336. }
  1337. dir = "./xlsx/abh/" + fileName + ".xlsx"
  1338. err = xf.Save(dir)
  1339. case "saleLeads":
  1340. xlsxArr := []string{"用户昵称", "姓名", "公司名称", "职位", "联系人电话", "购买条数", "用户邮箱", "已支付订单信息", "未支付订单类型", "销售线索来源", "具体来源", "数据需求"}
  1341. batch := FindBatch("abh")
  1342. fileName, detailName = time.Now().Format(date.Date_Short_Layout)+"-"+batch+"安博会电销销售线索", ""
  1343. xf := xlsx.NewFile()
  1344. style := xlsx.NewStyle()
  1345. style.Font.Size = 12
  1346. style.Font.Bold = true
  1347. style.Alignment.Vertical = "center"
  1348. style.Alignment.Horizontal = "center"
  1349. detailName = "今日新增安博会销售线索,请查收附件,及时跟进。"
  1350. sh, _ := xf.AddSheet("线索数据")
  1351. row1 := sh.AddRow()
  1352. for _, x := range xlsxArr {
  1353. cell := row1.AddCell()
  1354. cell.SetString(x)
  1355. cell.SetStyle(style)
  1356. }
  1357. filterArr := []string{"-pc", "-app", "-wx", "-h5"}
  1358. sourceMap := map[string]string{} //根据留资维表:tidb/Jianyu_subjectdb/d_saleleads_code
  1359. saleSource := TiDb.SelectBySql(`SELECT source,name FROM d_saleleads_code WHERE is_delete = 1`)
  1360. if saleSource != nil && len(*saleSource) > 0 {
  1361. for _, v := range *saleSource {
  1362. source := common.ObjToString(v["source"])
  1363. name := common.ObjToString(v["name"])
  1364. for _, s := range filterArr {
  1365. name = strings.ReplaceAll(name, s, "")
  1366. }
  1367. sourceMap[source] = name
  1368. }
  1369. }
  1370. for _, v := range data {
  1371. sources := common.ObjToString(v["source"])
  1372. interest := common.ObjToString(v["interest"])
  1373. row := sh.AddRow()
  1374. row.AddCell().SetString(common.ObjToString(v["usernickname"]))
  1375. row.AddCell().SetString(common.ObjToString(v["name"]))
  1376. row.AddCell().SetString(common.ObjToString(v["company"]))
  1377. row.AddCell().SetString(common.ObjToString(v["position"]))
  1378. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1379. row.AddCell().SetValue(0)
  1380. row.AddCell().SetString(common.ObjToString(v["email"]))
  1381. row.AddCell().SetString("")
  1382. row.AddCell().SetString("")
  1383. row.AddCell().SetString(sourceMap[sources])
  1384. row.AddCell().SetString(interest)
  1385. row.AddCell().SetString(common.ObjToString(v["data_requirement"]))
  1386. //增加客户需求
  1387. }
  1388. dir = "./xlsx/abh/" + fileName + ".xlsx"
  1389. err = xf.Save(dir)
  1390. case "big":
  1391. xlsxArr := []string{"用户昵称", "姓名", "公司名称", "职位", "联系人电话", "购买条数", "用户邮箱", "已支付订单信息", "未支付订单类型", "销售线索来源", "具体来源", "数据需求"}
  1392. batch := FindBatch("abh")
  1393. fileName, detailName = time.Now().Format(date.Date_Short_Layout)+"-"+batch+"安博会大客户销售线索", ""
  1394. xf := xlsx.NewFile()
  1395. style := xlsx.NewStyle()
  1396. style.Font.Size = 12
  1397. style.Font.Bold = true
  1398. style.Alignment.Vertical = "center"
  1399. style.Alignment.Horizontal = "center"
  1400. detailName = "今日新增安博会销售线索,请查收附件,及时跟进。"
  1401. sh, _ := xf.AddSheet("线索数据")
  1402. row1 := sh.AddRow()
  1403. for _, x := range xlsxArr {
  1404. cell := row1.AddCell()
  1405. cell.SetString(x)
  1406. cell.SetStyle(style)
  1407. }
  1408. for _, v := range data {
  1409. row := sh.AddRow()
  1410. row.AddCell().SetString(common.ObjToString(v["usernickname"]))
  1411. row.AddCell().SetString(common.ObjToString(v["username"]))
  1412. row.AddCell().SetString(common.ObjToString(v["company"]))
  1413. row.AddCell().SetString(common.ObjToString(v["job"]))
  1414. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1415. row.AddCell().SetValue(common.IntAll(v["data_count"]))
  1416. row.AddCell().SetString(common.ObjToString(v["email"]))
  1417. row.AddCell().SetString(common.ObjToString(v["payorderinfo"]))
  1418. row.AddCell().SetString(common.ObjToString(v["unpayorderinfo"]))
  1419. row.AddCell().SetString(common.ObjToString(v["source"]))
  1420. row.AddCell().SetString(common.ObjToString(v["interest"]))
  1421. row.AddCell().SetString(common.ObjToString(v["data_requirement"]))
  1422. //增加客户需求
  1423. }
  1424. dir = "./xlsx/abh/" + fileName + ".xlsx"
  1425. err = xf.Save(dir)
  1426. case "advisory":
  1427. xlsxArr := []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"}
  1428. //排序:首先按照“联系方式”排序,即同1个用户的留资放在一起,其次按照留资时间正序排序。
  1429. batch := FindBatch("abh")
  1430. fileName, detailName = "安博会咨询服务销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, ""
  1431. xf := xlsx.NewFile()
  1432. style := xlsx.NewStyle()
  1433. style.Font.Size = 12
  1434. style.Font.Bold = true
  1435. style.Alignment.Vertical = "center"
  1436. style.Alignment.Horizontal = "center"
  1437. detailName = "今日新增安博会销售线索,请查收附件,及时跟进。"
  1438. sh, _ := xf.AddSheet("线索数据")
  1439. row1 := sh.AddRow()
  1440. for _, x := range xlsxArr {
  1441. cell := row1.AddCell()
  1442. cell.SetString(x)
  1443. cell.SetStyle(style)
  1444. }
  1445. for _, v := range data {
  1446. row := sh.AddRow()
  1447. row.AddCell().SetString(common.ObjToString(v["username"]))
  1448. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1449. row.AddCell().SetString(common.ObjToString(v["email"]))
  1450. row.AddCell().SetString(common.ObjToString(v["company"]))
  1451. row.AddCell().SetString(common.ObjToString(v["data_requirement"]))
  1452. row.AddCell().SetString(common.ObjToString(v["source"]))
  1453. row.AddCell().SetString(common.ObjToString(v["interest"]))
  1454. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  1455. }
  1456. dir = "./xlsx/abh/" + fileName + ".xlsx"
  1457. err = xf.Save(dir)
  1458. case "market":
  1459. xlsxArr := []string{"姓名", "联系人电话", "公司名称", "职位", "部门", "销售线索来源", "留资时间"}
  1460. batch := FindBatch("abh")
  1461. fileName, detailName = "安博会商务合作销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, ""
  1462. xf := xlsx.NewFile()
  1463. style := xlsx.NewStyle()
  1464. style.Font.Size = 12
  1465. style.Font.Bold = true
  1466. style.Alignment.Vertical = "center"
  1467. style.Alignment.Horizontal = "center"
  1468. detailName = "今日新增安博会销售线索,请查收附件,及时跟进。"
  1469. sh, _ := xf.AddSheet("线索数据")
  1470. row1 := sh.AddRow()
  1471. for _, x := range xlsxArr {
  1472. cell := row1.AddCell()
  1473. cell.SetString(x)
  1474. cell.SetStyle(style)
  1475. }
  1476. for _, v := range data {
  1477. row := sh.AddRow()
  1478. row.AddCell().SetString(common.ObjToString(v["username"]))
  1479. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1480. row.AddCell().SetString(common.ObjToString(v["company"]))
  1481. row.AddCell().SetString(common.ObjToString(v["job"]))
  1482. row.AddCell().SetString(common.ObjToString(v["branch"]))
  1483. row.AddCell().SetString(common.ObjToString(v["source"]))
  1484. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  1485. //增加客户需求
  1486. }
  1487. dir = "./xlsx/abh/" + fileName + ".xlsx"
  1488. err = xf.Save(dir)
  1489. }
  1490. email = db.AbhEmail
  1491. if err != nil {
  1492. log.Println("xls error", err, dir)
  1493. } else {
  1494. gmail := &mail.GmailAuth{
  1495. SmtpHost: "smtp.exmail.qq.com",
  1496. SmtpPort: 465,
  1497. User: "public03@topnet.net.cn",
  1498. Pwd: "ue9Rg9Sf4CVtdm5a",
  1499. }
  1500. status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", gmail)
  1501. if status {
  1502. log.Println("send mail success", fileName, email)
  1503. }
  1504. }
  1505. }*/
  1506. // 安防邮件
  1507. func AFEmail(data []map[string]interface{}) {
  1508. xlsxArr := []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"}
  1509. batch := FindBatch("af")
  1510. fileName, detailName := "安防销售线索 "+time.Now().Format(date.Date_Short_Layout)+"-"+batch, ""
  1511. xf := xlsx.NewFile()
  1512. style := xlsx.NewStyle()
  1513. style.Font.Size = 12
  1514. style.Font.Bold = true
  1515. style.Alignment.Vertical = "center"
  1516. style.Alignment.Horizontal = "center"
  1517. detailName = "今日新增安防销售线索,请查收附件,及时跟进。"
  1518. sh, _ := xf.AddSheet("线索数据")
  1519. row1 := sh.AddRow()
  1520. for _, x := range xlsxArr {
  1521. cell := row1.AddCell()
  1522. cell.SetString(x)
  1523. cell.SetStyle(style)
  1524. }
  1525. for _, v := range data {
  1526. row := sh.AddRow()
  1527. row.AddCell().SetString(common.ObjToString(v["name"]))
  1528. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1529. row.AddCell().SetString(common.ObjToString(v["email"]))
  1530. row.AddCell().SetString(common.ObjToString(v["company_name"]))
  1531. row.AddCell().SetString("")
  1532. row.AddCell().SetString("")
  1533. row.AddCell().SetString("首次使用安防新注册")
  1534. row.AddCell().SetString(gconv.String(v["time"]))
  1535. //增加客户需求
  1536. }
  1537. email := db.AfEmail
  1538. dir := "./xlsx/af/" + fileName + ".xlsx"
  1539. err := xf.Save(dir)
  1540. if err != nil {
  1541. log.Println("xls error", err, dir)
  1542. } else {
  1543. gmail := &mail.GmailAuth{
  1544. SmtpHost: db.Mail.SmtpHost,
  1545. SmtpPort: db.Mail.SmtpPort,
  1546. User: db.Mail.User,
  1547. Pwd: db.Mail.Pwd,
  1548. }
  1549. status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, "", gmail)
  1550. if status {
  1551. log.Println("send mail success", fileName, email)
  1552. }
  1553. }
  1554. }
  1555. func ABHEmail(source string, data []map[string]interface{}) {
  1556. var fileName, detailName, dir string
  1557. var err error
  1558. xlsxArr, detailName := getExcelHeaderAndDetail(source)
  1559. batch := FindBatch("abh")
  1560. fileName = fmt.Sprintf("%s %s-%s", getFileNamePrefix(source), time.Now().Format(date.Date_Short_Layout), batch)
  1561. xf := xlsx.NewFile()
  1562. style := createExcelStyle()
  1563. sh, _ := xf.AddSheet("线索数据")
  1564. addHeaderRow(sh, xlsxArr, style)
  1565. switch source {
  1566. case "user":
  1567. err = populateUserData(sh, data)
  1568. case "saleLeads", "big":
  1569. err = populateSaleLeadData(sh, data)
  1570. case "advisory":
  1571. err = populateAdvisoryData(sh, data)
  1572. case "market", "selection":
  1573. err = populateMarketData(sh, data)
  1574. }
  1575. if err == nil {
  1576. dir = fmt.Sprintf("./xlsx/abh/%s.xlsx", fileName)
  1577. err = xf.Save(dir)
  1578. }
  1579. sendEmailIfSuccessful(err, fileName, detailName, dir)
  1580. }
  1581. func getExcelHeaderAndDetail(source string) ([]string, string) {
  1582. switch source {
  1583. case "user":
  1584. return []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"}, "今日新增安博会销售线索,请查收附件,及时跟进。"
  1585. case "saleLeads":
  1586. return []string{"用户昵称", "姓名", "公司名称", "职位", "联系人电话", "购买条数", "用户邮箱", "已支付订单信息", "未支付订单类型", "销售线索来源", "具体来源", "数据需求"}, "今日新增安博会销售线索,请查收附件,及时跟进。"
  1587. case "big":
  1588. return []string{"用户昵称", "姓名", "公司名称", "职位", "联系人电话", "购买条数", "用户邮箱", "已支付订单信息", "未支付订单类型", "销售线索来源", "具体来源", "数据需求"}, "今日新增安博会销售线索,请查收附件,及时跟进。"
  1589. case "advisory":
  1590. return []string{"姓名", "联系方式", "邮箱", "公司名称", "咨询需求", "销售线索来源", "具体来源", "留资时间"}, "今日新增安博会销售线索,请查收附件,及时跟进。"
  1591. case "market":
  1592. return []string{"姓名", "联系人电话", "公司名称", "职位", "部门", "销售线索来源", "留资时间"}, "今日新增安博会销售线索,请查收附件,及时跟进。"
  1593. case "selection":
  1594. return []string{"姓名", "联系人电话", "公司名称", "职位", "部门", "销售线索来源", "留资时间"}, "今日新增安博会销售线索,请查收附件,及时跟进。"
  1595. default:
  1596. return nil, ""
  1597. }
  1598. }
  1599. func getFileNamePrefix(source string) string {
  1600. switch source {
  1601. case "user":
  1602. return "安博会用户注册销售线索"
  1603. case "saleLeads":
  1604. return "安博会电销销售线索"
  1605. case "big":
  1606. return "安博会大客户销售线索"
  1607. case "advisory":
  1608. return "安博会咨询服务销售线索"
  1609. case "market":
  1610. return "安博会商务合作销售线索"
  1611. default:
  1612. return "未知线索"
  1613. }
  1614. }
  1615. func createExcelStyle() *xlsx.Style {
  1616. style := xlsx.NewStyle()
  1617. style.Font.Size = 12
  1618. style.Font.Bold = true
  1619. style.Alignment.Vertical = "center"
  1620. style.Alignment.Horizontal = "center"
  1621. return style
  1622. }
  1623. func addHeaderRow(sh *xlsx.Sheet, headers []string, style *xlsx.Style) {
  1624. row := sh.AddRow()
  1625. for _, header := range headers {
  1626. cell := row.AddCell()
  1627. cell.SetString(header)
  1628. cell.SetStyle(style)
  1629. }
  1630. }
  1631. func populateUserData(sh *xlsx.Sheet, data []map[string]interface{}) error {
  1632. for _, v := range data {
  1633. row := sh.AddRow()
  1634. row.AddCell().SetString(common.ObjToString(v["name"]))
  1635. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1636. row.AddCell().SetString(common.ObjToString(v["email"]))
  1637. row.AddCell().SetString(common.ObjToString(v["company_name"]))
  1638. row.AddCell().SetString("")
  1639. row.AddCell().SetString("")
  1640. row.AddCell().SetString("安博会用户注册")
  1641. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  1642. }
  1643. return nil
  1644. }
  1645. func populateSaleLeadData(sh *xlsx.Sheet, data []map[string]interface{}) error {
  1646. sourceMap := buildSourceMap("运营部")
  1647. for _, v := range data {
  1648. row := sh.AddRow()
  1649. row.AddCell().SetString(common.ObjToString(v["usernickname"]))
  1650. row.AddCell().SetString(common.ObjToString(v["name"]))
  1651. row.AddCell().SetString(common.ObjToString(v["company"]))
  1652. row.AddCell().SetString(common.ObjToString(v["position"]))
  1653. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1654. row.AddCell().SetValue(0)
  1655. row.AddCell().SetString(common.ObjToString(v["email"]))
  1656. row.AddCell().SetString("")
  1657. row.AddCell().SetString("")
  1658. row.AddCell().SetString(sourceMap[common.ObjToString(v["source"])])
  1659. row.AddCell().SetString(common.ObjToString(v["interest"]))
  1660. row.AddCell().SetString(common.ObjToString(v["data_requirement"]))
  1661. }
  1662. return nil
  1663. }
  1664. func populateAdvisoryData(sh *xlsx.Sheet, data []map[string]interface{}) error {
  1665. for _, v := range data {
  1666. row := sh.AddRow()
  1667. row.AddCell().SetString(common.ObjToString(v["username"]))
  1668. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1669. row.AddCell().SetString(common.ObjToString(v["email"]))
  1670. row.AddCell().SetString(common.ObjToString(v["company"]))
  1671. row.AddCell().SetString(common.ObjToString(v["data_requirement"]))
  1672. row.AddCell().SetString(common.ObjToString(v["source"]))
  1673. row.AddCell().SetString(common.ObjToString(v["interest"]))
  1674. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  1675. }
  1676. return nil
  1677. }
  1678. func populateMarketData(sh *xlsx.Sheet, data []map[string]interface{}) error {
  1679. for _, v := range data {
  1680. row := sh.AddRow()
  1681. row.AddCell().SetString(common.ObjToString(v["username"]))
  1682. row.AddCell().SetString(common.ObjToString(v["phone"]))
  1683. row.AddCell().SetString(common.ObjToString(v["company"]))
  1684. row.AddCell().SetString(common.ObjToString(v["job"]))
  1685. row.AddCell().SetString(common.ObjToString(v["branch"]))
  1686. row.AddCell().SetString(common.ObjToString(v["source"]))
  1687. row.AddCell().SetString(gconv.Time(gconv.Int64(v["createtime"])).Format(date.Date_Full_Layout))
  1688. }
  1689. return nil
  1690. }
  1691. func sendEmailIfSuccessful(err error, fileName, detailName, dir string) {
  1692. if err != nil {
  1693. log.Println("xls error", err, dir)
  1694. return
  1695. }
  1696. email := db.AbhEmail
  1697. gmail := &mail.GmailAuth{
  1698. SmtpHost: db.Mail.SmtpHost,
  1699. SmtpPort: db.Mail.SmtpPort,
  1700. User: db.Mail.User,
  1701. Pwd: db.Mail.Pwd,
  1702. }
  1703. status := mail.GSendMail_q("剑鱼标讯", email, "", "", fileName, detailName, dir, fileName+".xlsx", gmail)
  1704. if status {
  1705. log.Println("send mail success", fileName, email)
  1706. }
  1707. }
  1708. // 邀请用户处理
  1709. func inviteUser() {
  1710. log.Println("邀请用户处理开始")
  1711. //判断节假日
  1712. runOk := getRunOk()
  1713. if !runOk {
  1714. log.Println("不是工作日,任务暂停")
  1715. return
  1716. }
  1717. rebindTimeEnd := cfg.InviteTime
  1718. sql := fmt.Sprintf(`select * from user_statistics where createTime > "%s" order by createTime asc`, rebindTimeEnd)
  1719. //sql := fmt.Sprintf(`select * from user_statistics where createTime = "%s" order by createTime asc`, rebindTimeEnd)
  1720. data := BiService.SelectBySql(sql)
  1721. if data != nil && *data != nil && len(*data) > 0 {
  1722. for _, v := range *data {
  1723. rebindTimeEnd = common.ObjToString(v["createTime"])
  1724. event := gconv.Int64(v["event"])
  1725. switch event {
  1726. case 1:
  1727. v["sourceCode"] = "736"
  1728. case 2:
  1729. v["sourceCode"] = "737"
  1730. case 3:
  1731. v["sourceCode"] = "738"
  1732. }
  1733. v["user_id"] = gconv.String(v["userId"])
  1734. ok1, ok2, _ := FormatData(v, "invite")
  1735. if !ok1 {
  1736. log.Println("线索卡点", "invite", v, rebindTimeEnd)
  1737. } else {
  1738. if !ok2 {
  1739. log.Println("用户分配已达上限", "invite", v, rebindTimeEnd)
  1740. }
  1741. }
  1742. }
  1743. cfg.InviteTime = rebindTimeEnd
  1744. common.WriteSysConfig(&cfg)
  1745. }
  1746. log.Println("邀请用户处理结束")
  1747. }
  1748. // 开年活动
  1749. func nextYearActivity() {
  1750. log.Println("开年活动处理开始")
  1751. //判断节假日
  1752. runOk := getRunOk()
  1753. if !runOk {
  1754. log.Println("不是工作日,任务暂停")
  1755. return
  1756. }
  1757. activityTimeEnd := cfg.ActivityTime
  1758. sql := fmt.Sprintf(`SELECT
  1759. a.*
  1760. FROM
  1761. jyactivities.lottery_user_account a
  1762. INNER JOIN jyactivities.lottery_prize_info b on a.create_time > "%s" and a.prize_id=b.id
  1763. INNER JOIN jyactivities.prize_base_info c on c.name like "%s" and b.pb_id=c.id
  1764. ORDER BY
  1765. a.create_time ASC
  1766. `, activityTimeEnd, "%超级订阅%")
  1767. data := Mysql.SelectBySql(sql)
  1768. if data != nil && *data != nil && len(*data) > 0 {
  1769. for _, v := range *data {
  1770. activityTimeEnd = common.ObjToString(v["create_time"])
  1771. v["sourceCode"] = gconv.Int64(v["active_id"])
  1772. v["user_id"] = gconv.String(v["mgo_user_id"])
  1773. ok1, ok2, _ := FormatData(v, "activity")
  1774. if !ok1 {
  1775. log.Println("线索卡点", "activity", v, activityTimeEnd)
  1776. } else {
  1777. if !ok2 {
  1778. log.Println("开年活动分配已达上限", "activity", v, activityTimeEnd)
  1779. }
  1780. }
  1781. }
  1782. cfg.ActivityTime = activityTimeEnd
  1783. common.WriteSysConfig(&cfg)
  1784. }
  1785. log.Println("开年活动处理结束")
  1786. }
  1787. // AddLockeStatusChange
  1788. // 锁定状态变更记录
  1789. // '锁定状态,1:已锁定,2:未锁定,3:无需锁定',
  1790. func AddLockeStatusChange(tx *sql.Tx, clueId, oldPositionId, newPositionId, oldLockStatus int64, isGroup, isCommerce int, nowTime, clueName, operateType string) int64 {
  1791. // operateType 操作类型 add 新增 delete 删除
  1792. //需要批量查处理 后期处理
  1793. if oldLockStatus == 3 {
  1794. return 0
  1795. }
  1796. newLockStatus := LockStatusHandle(isGroup, isCommerce, oldLockStatus)
  1797. if clueName == "" {
  1798. log.Println("m")
  1799. return 0
  1800. }
  1801. nowPositionId, clueList, lockClueList := FindRelatedClueData(clueName, isGroup, isCommerce)
  1802. if operateType == "add" && newPositionId == 0 {
  1803. //锁定人看有没有人员变更 没有人员变更从其他数据上边去
  1804. newPositionId = nowPositionId
  1805. }
  1806. if operateType == "add" && newPositionId > 0 {
  1807. //新增变更
  1808. //变更
  1809. if newLockStatus != oldLockStatus {
  1810. //状态变更
  1811. for _, v := range clueList {
  1812. nowLockStatus := gconv.Int64(v["lock_status"])
  1813. clueId := gconv.Int64(v["id"])
  1814. TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{
  1815. "id": clueId,
  1816. }, map[string]interface{}{
  1817. "lock_status": newLockStatus,
  1818. "lock_position_id": newPositionId,
  1819. })
  1820. //新增进来的
  1821. if nowLockStatus != newLockStatus {
  1822. UpdateLockStatus(clueId, newLockStatus)
  1823. AddChangeRecord(nil, clueId, newPositionId, "lock_status", "基本信息变更", CodeLock[newLockStatus], CodeLock[oldLockStatus], nowTime, "", -1)
  1824. }
  1825. if oldPositionId != newPositionId {
  1826. //锁定人变更
  1827. UpdateLockPositionId(clueId, newPositionId)
  1828. AddChangeRecord(nil, clueId, newPositionId, "lock_position_id", "锁定人变更", FindPositionToName(newPositionId), FindPositionToName(oldPositionId), nowTime, "", -1)
  1829. }
  1830. }
  1831. return 1
  1832. }
  1833. if oldPositionId != newPositionId && newLockStatus == oldLockStatus {
  1834. //只变人员 不变状态
  1835. _, clueList, _ := FindRelatedClueData(clueName, isGroup, isCommerce)
  1836. for _, v := range clueList {
  1837. clueId := gconv.Int64(v["id"])
  1838. //锁定人变更
  1839. UpdateLockPositionId(clueId, newPositionId)
  1840. AddChangeRecord(nil, clueId, newPositionId, "lock_position_id", "锁定人变更", FindPositionToName(newPositionId), FindPositionToName(oldPositionId), nowTime, "", -1)
  1841. }
  1842. }
  1843. } else {
  1844. //全部删除
  1845. isChecked := false
  1846. if len(lockClueList) == 1 {
  1847. //判断是不是只有一条选中
  1848. id := gconv.Int64(lockClueList[0]["id"])
  1849. if id == clueId {
  1850. isChecked = true
  1851. }
  1852. }
  1853. if isChecked {
  1854. //所有数据都要取消状态
  1855. newLockStatus := int64(2)
  1856. if isGroup == 1 && isCommerce != 3 {
  1857. newLockStatus = 3
  1858. }
  1859. for _, v := range clueList {
  1860. clueId := gconv.Int64(v["id"])
  1861. TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{
  1862. "id": clueId,
  1863. }, map[string]interface{}{
  1864. "lock_status": newLockStatus,
  1865. "lock_position_id": 0,
  1866. })
  1867. if isGroup == 0 && isCommerce == 1 {
  1868. UpdateLockPositionId(clueId, oldPositionId)
  1869. }
  1870. AddChangeRecord(nil, clueId, oldPositionId, "lock_position_id", "锁定人变更", "/", FindPositionToName(oldPositionId), nowTime, "", -1)
  1871. }
  1872. }
  1873. }
  1874. return 1
  1875. }
  1876. // 关联公司线索查询
  1877. func FindRelatedClueData(companyName string, isGroup, isCommerce int) (int64, []map[string]interface{}, []map[string]interface{}) {
  1878. sqlStr := ""
  1879. if isGroup == 0 && isCommerce == 1 {
  1880. sqlStr = fmt.Sprintf(`SELECT
  1881. *
  1882. FROM
  1883. dwd_f_crm_clue_info
  1884. WHERE
  1885. cluename IN ( SELECT companyName FROM ( SELECT b_name AS companyName FROM ent_relation WHERE a_name ="%s" UNION SELECT a_name AS companyName FROM ent_relation WHERE b_name = "%s") ) or cluename="%s" `, companyName, companyName, companyName)
  1886. } else {
  1887. sqlStr = fmt.Sprintf(`SELECT
  1888. *
  1889. FROM
  1890. dwd_f_crm_clue_info
  1891. WHERE
  1892. cluename="%s" `, companyName)
  1893. }
  1894. clueList := TiDb.SelectBySql(sqlStr)
  1895. if clueList == nil || len(*clueList) == 0 {
  1896. return 0, []map[string]interface{}{}, []map[string]interface{}{}
  1897. }
  1898. positionId := int64(0)
  1899. var clueArr []map[string]interface{}
  1900. var lockClueArr []map[string]interface{}
  1901. for _, v := range *clueList {
  1902. if gconv.Int64(v["position_id"]) > 0 {
  1903. positionId = gconv.Int64(v["position_id"])
  1904. lockClueArr = append(lockClueArr, v)
  1905. }
  1906. clueArr = append(clueArr, v)
  1907. }
  1908. return positionId, clueArr, lockClueArr
  1909. }
  1910. // LockStatusHandle 锁定状态逻辑
  1911. /*
  1912. 1 已锁定:“线索名称”为非集团公司且在工商库,且有销售人员在跟进(注:线索名称为非集团公司但不在工商库,即此时线索名称不规范或不完整,即使在私海,也非锁定状态);
  1913. 2 未锁定:不符合“无需锁定”和“已锁定”条件的,则为“未锁定”;
  1914. 3 无需锁定:“线索名称”为集团公司。
  1915. */
  1916. func LockStatusHandle(isGroup, isCommerce int, oldLockStatus int64) int64 {
  1917. newLockStatus := int64(2)
  1918. if isGroup == 1 && isCommerce != 3 {
  1919. //无需锁定处理
  1920. if oldLockStatus != 3 {
  1921. newLockStatus = 3
  1922. }
  1923. } else if isGroup == 0 && isCommerce == 1 {
  1924. //已锁定处理
  1925. newLockStatus = 1
  1926. }
  1927. return newLockStatus
  1928. }
  1929. func FindRelatedData(companyName string, isGroup, isCommerce int) []string {
  1930. sqlStr := ""
  1931. if isGroup == 0 && isCommerce == 1 {
  1932. sqlStr = fmt.Sprintf(`SELECT companyName FROM
  1933. ( SELECT b_name AS companyName FROM ent_relation WHERE a_name ="%s"
  1934. UNION
  1935. SELECT a_name AS companyName FROM ent_relation WHERE b_name = "%s")`, companyName, companyName)
  1936. }
  1937. companyList := TiDb.SelectBySql(sqlStr)
  1938. if companyList == nil || len(*companyList) == 0 {
  1939. return []string{companyName}
  1940. }
  1941. var companyArr []string
  1942. for _, v := range *companyList {
  1943. companyName := gconv.String(v["companyName"])
  1944. companyArr = append(companyArr, companyName)
  1945. }
  1946. companyArr = append(companyArr, companyName)
  1947. return companyArr
  1948. }
  1949. // 老公司数据处理
  1950. func ClueNameChange(oldCompanyName string, oldLockStatus int64, clueId int64) {
  1951. //老的需要清除一下
  1952. nowTime := time.Now().Format("2006-01-02 15:04:05")
  1953. isGroup, isCommerce := int(0), int(0)
  1954. if oldCompanyName == "" {
  1955. log.Println(oldCompanyName, "这个公司是空的")
  1956. return
  1957. }
  1958. //是否是集团
  1959. if c := TiDb.CountBySql(`select count(1) from group_company_name where company_name=?`, oldCompanyName); c > 0 {
  1960. isGroup = 1
  1961. }
  1962. //是否在工商库
  1963. if oldCompanyName != "" {
  1964. /*if c := MgoQyxy.Count("qyxy_std", map[string]interface{}{"company_name": oldCompanyName, "company_type": map[string]interface{}{"$ne": "个体工商户"}}); c > 0 {
  1965. isCommerce = 1
  1966. }*/
  1967. isCommerce = 1
  1968. }
  1969. //老的线索名称看看要不要处理
  1970. if isGroup == 0 && isCommerce == 1 {
  1971. if oldLockStatus == 1 {
  1972. //已锁定可能变未锁定
  1973. _, clueList, _ := FindRelatedClueData(oldCompanyName, isGroup, isCommerce)
  1974. //状态变更
  1975. isChange := false
  1976. for _, v := range clueList {
  1977. clueid := gconv.Int64(v["id"])
  1978. positionId := gconv.Int64(v["position_id"])
  1979. if clueid == clueId {
  1980. continue
  1981. }
  1982. if positionId > 0 {
  1983. isChange = true
  1984. break
  1985. }
  1986. }
  1987. if !isChange {
  1988. //说明还有其他能决定绑定id的
  1989. newLockStatus := int64(2)
  1990. for _, v := range clueList {
  1991. clueid := gconv.Int64(v["id"])
  1992. if clueid == clueId {
  1993. continue
  1994. }
  1995. positionId := gconv.Int64(v["position_id"])
  1996. TiDb.Update("dwd_f_crm_clue_info", map[string]interface{}{
  1997. "id": clueId,
  1998. }, map[string]interface{}{
  1999. "lock_status": newLockStatus,
  2000. "lock_position_id": nil,
  2001. })
  2002. //新增进来的
  2003. UpdateLockStatus(clueid, newLockStatus)
  2004. AddChangeRecord(nil, clueid, 0, "lock_status", "基本信息变更", CodeLock[newLockStatus], CodeLock[oldLockStatus], nowTime, "", -1)
  2005. //锁定人变更
  2006. UpdateLockPositionId(clueid, 0)
  2007. AddChangeRecord(nil, clueid, 0, "lock_position_id", "锁定人变更", FindPositionToName(0), FindPositionToName(positionId), nowTime, "", -1)
  2008. }
  2009. }
  2010. }
  2011. }
  2012. return
  2013. }