customer.go 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. package customer
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "math/rand"
  6. "spaceofcheng/services/models"
  7. "spaceofcheng/services/models/card"
  8. "spaceofcheng/services/models/cases"
  9. "spaceofcheng/services/models/coupon"
  10. "spaceofcheng/services/models/customer"
  11. "spaceofcheng/services/models/model"
  12. "spaceofcheng/services/models/system"
  13. "spaceofcheng/services/service"
  14. "spaceofcheng/services/service/events"
  15. "spaceofcheng/services/utils"
  16. "strconv"
  17. "strings"
  18. "time"
  19. )
  20. // CustomerServ 系统处理
  21. type CustomerServ struct {
  22. ctx *utils.Context
  23. dao *customer.CustomerDAO
  24. casedao *cases.CaseDAO
  25. userdao *system.UserDAO
  26. carddao *card.CardDAO
  27. coupondao *coupon.CouponDAO
  28. }
  29. // NewCustomerServ 初始化
  30. func NewCustomerServ(ctx *utils.Context) *CustomerServ {
  31. return &CustomerServ{
  32. ctx: ctx,
  33. dao: customer.NewCustomerDAO(ctx),
  34. casedao: cases.NewCaseDAO(ctx),
  35. userdao: system.NewUserDAO(ctx),
  36. carddao: card.NewCardDAO(ctx),
  37. coupondao: coupon.NewCouponDAO(ctx),
  38. }
  39. }
  40. // GetCustWithWXList 获取客户列表
  41. func (s *CustomerServ) GetCustWithWXList(phone, username, recommendname, begindate, enddate, caseids string, page, pageSize int) (map[string]interface{}, error) {
  42. if pageSize == 0 {
  43. pageSize = service.PAGENUM
  44. }
  45. cust, err := s.dao.CustWithWXList(phone, username, recommendname, begindate, enddate, caseids, page, pageSize)
  46. if err != nil {
  47. utils.LogError("获取客户列表失败: " + err.Error())
  48. return nil, errors.New("获取客户列表失败")
  49. }
  50. total, err := s.dao.CustWithWXListCount(phone, username, recommendname, begindate, enddate, caseids)
  51. if err != nil {
  52. utils.LogError("获取客户列表失败: " + err.Error())
  53. return nil, errors.New("获取客户列表失败")
  54. }
  55. return map[string]interface{}{
  56. "list": cust,
  57. "pageSize": pageSize,
  58. "pagenum": total,
  59. "page": page,
  60. }, nil
  61. }
  62. // GetCustWithWXByID 获取客户列表
  63. func (s *CustomerServ) GetCustWithWXByID(custID string) (*customer.CustWithWX, error) {
  64. cust, err := s.dao.GetCustWithWXByID(custID)
  65. if err != nil {
  66. utils.LogError(err.Error())
  67. return nil, err
  68. }
  69. if cust.Status != models.STATUS_NORMAL {
  70. return nil, errors.New("用户状态异常")
  71. }
  72. return cust, nil
  73. }
  74. // GetCustUserByOpenID 根据openid获取用户信息
  75. func (s *CustomerServ) GetCustUserByOpenID(openid string) (*customer.CustWithWX, error) {
  76. cust, err := s.dao.GetCustWithWXByOpenID(openid)
  77. if err != nil {
  78. utils.LogError(err.Error())
  79. return nil, err
  80. }
  81. if cust != nil && cust.MapUser != "" {
  82. caseinfo, err := s.userdao.GetUserBelongCase(cust.MapUser)
  83. if err != nil {
  84. utils.LogError(err.Error())
  85. return nil, err
  86. }
  87. cust.BelongCaseId = caseinfo.CaseId
  88. cust.BelongCaseStatus = caseinfo.Status
  89. }
  90. return cust, nil
  91. }
  92. // GetCustUserByID 获取用户信息(自定义内容)
  93. func (s *CustomerServ) GetCustUserByID(userID string) (*UserProfile, error) {
  94. user, err := s.dao.GetUserByID(userID)
  95. if err != nil {
  96. utils.LogError(err.Error())
  97. return nil, err
  98. }
  99. if user.Status != models.STATUS_NORMAL {
  100. return nil, errors.New("用户状态异常")
  101. }
  102. userProfile := UserProfile{
  103. UserId: user.UserId,
  104. UserName: user.UserName,
  105. RealName: user.RealName,
  106. Sex: user.Sex,
  107. WorkNo: user.WorkNo,
  108. Email: user.Email,
  109. Phone: user.Phone,
  110. Headimgurl: user.Headimgurl,
  111. }
  112. return &userProfile, nil
  113. }
  114. // BindWechatUser 绑定微信用户
  115. func (s *CustomerServ) BindWechatUser(userMap *model.TaUserMapping, phone string) (*model.TaCustomer, error) {
  116. user, err := s.dao.GetUserByPhone(phone)
  117. if err != nil {
  118. utils.LogError(err.Error())
  119. return nil, err
  120. }
  121. if user == nil {
  122. return nil, errors.New("您不是系统人员,无法登录")
  123. }
  124. cust, err := s.dao.GetCustomerByPhone(phone)
  125. if err != nil {
  126. utils.LogError(err.Error())
  127. return nil, err
  128. }
  129. if cust == nil {
  130. wxInfo := utils.WechatUser{}
  131. if err := json.Unmarshal([]byte(userMap.AccountInfo), &wxInfo); err != nil {
  132. utils.LogError("解析用户微信映射信息失败: " + err.Error())
  133. return nil, errors.New("系统数据异常")
  134. }
  135. // 更新用户手机号码信息及userid信息
  136. customer, err := s.dao.GetCustWithWXByOpenID(wxInfo.OpenID)
  137. if err != nil {
  138. utils.LogError("查询用户失败: " + err.Error())
  139. return nil, errors.New("校验用户数据失败")
  140. }
  141. newCust := model.TaCustomer{
  142. CustomerId: customer.CustomerId,
  143. Phone: user.Phone,
  144. UserId: user.UserId,
  145. }
  146. err = s.dao.UpdateCustomer(&newCust, []string{
  147. "phone",
  148. "user_id",
  149. })
  150. if err != nil {
  151. utils.LogError(err.Error())
  152. return nil, err
  153. }
  154. cust = &newCust
  155. } else {
  156. if cust.Status != models.STATUS_NORMAL {
  157. return nil, errors.New("用户状态不正确")
  158. }
  159. }
  160. // triggerRegiteEvent 触发注册事件
  161. // evtEngID := utils.EngineIDBy(cust.OrgId, cust.RecommendCase)
  162. // utils.EventEngineBus(evtEngID).EmitEvent(events.EvtRegiste, *cust)
  163. // if cust.CustomerId == userMap.UserId {
  164. // return cust, nil
  165. // }
  166. // 更新用户映射信息
  167. userMap.UserId = cust.CustomerId
  168. if err := s.dao.UpdateUserMapping(userMap, []string{"user_id"}); err != nil {
  169. utils.LogError("更新用户映射信息失败:" + err.Error())
  170. return nil, errors.New("映射用户信息失败")
  171. }
  172. return cust, nil
  173. }
  174. func (s *CustomerServ) GenerateCustomerBarcode() string {
  175. temp1 := "63"
  176. temp2 := time.Now().Local().Format("060102")
  177. temp3 := strconv.Itoa(rand.Intn(9) * 87)
  178. if len(temp3) < 3 {
  179. temp3 += strconv.Itoa(rand.Intn(9))
  180. }
  181. temp4 := strconv.Itoa(rand.Intn(9))
  182. temp5, _ := models.GetSeqID(temp2)
  183. minus := 4 - len(temp5)
  184. if minus < 0 {
  185. minus = 0
  186. temp5 = temp5[0:4]
  187. }
  188. temp5 = strings.Repeat("0", minus) + temp5
  189. code := temp1 + temp2 + temp3 + temp4 + temp5
  190. return code
  191. }
  192. // BindWechatCust 绑定微信用户
  193. func (s *CustomerServ) BindWechatCust(userMap *model.TaUserMapping, phone, recommendCode, name string) (*model.TaCustomer, error) {
  194. cust, err := s.dao.GetCustomerByPhone(phone)
  195. if err != nil {
  196. utils.LogError(err.Error())
  197. return nil, err
  198. }
  199. if cust != nil {
  200. return nil, errors.New("当前手机号已被绑定或者注册")
  201. }
  202. // 用户不存在, 则新增
  203. wxInfo := utils.WechatUser{}
  204. if err := json.Unmarshal([]byte(userMap.AccountInfo), &wxInfo); err != nil {
  205. utils.LogError("解析用户微信映射信息失败: " + err.Error())
  206. return nil, errors.New("系统数据异常")
  207. }
  208. // 更新用户手机号码信息及userid信息
  209. customer, err := s.dao.GetCustWithWXByOpenID(wxInfo.OpenID)
  210. if err != nil {
  211. return nil, utils.LogError("获取用户信息失败", err.Error())
  212. }
  213. var barcode string
  214. newCust := customer.TaCustomer
  215. for i := 0; i < 10; i++ {
  216. barcode = s.GenerateCustomerBarcode()
  217. x, err := s.dao.IsBarcodeExist(barcode)
  218. if err != nil {
  219. return nil, errors.New("生成条形码失败")
  220. }
  221. if x <= 0 {
  222. break
  223. }
  224. }
  225. newCust.Barcode = barcode
  226. newCust.Phone = phone
  227. newCust.Name = name
  228. newCust.BindingDate = time.Now().Local()
  229. // 校验案场信息
  230. if recommendCode != "" {
  231. user, err := s.dao.GetSalesByRecommendCode(recommendCode)
  232. if err != nil {
  233. utils.LogError(err.Error())
  234. return nil, err
  235. }
  236. userCase, err := s.dao.GetSalesCaseById(user.UserId)
  237. cs, err := s.casedao.GetCaseByID(userCase.CaseId)
  238. if err != nil {
  239. utils.LogError(err.Error())
  240. return nil, err
  241. }
  242. if cs == nil || cs.Status == models.STATUS_DEL {
  243. return nil, errors.New("系统无该推荐案场")
  244. }
  245. if cs.Status == 0 {
  246. return nil, errors.New("该案场暂未开放")
  247. }
  248. newCust.OrgId = cs.OrgId
  249. newCust.RecommendCase = cs.CaseId
  250. if user == nil || user.Status == models.STATUS_DEL {
  251. return nil, errors.New("系统无该推荐人")
  252. }
  253. newCust.OrgId = user.OrgId
  254. newCust.RecommendId = user.UserId
  255. newCust.RecommendName = user.RealName
  256. }
  257. // 校验推荐人
  258. // if userID != "" {
  259. // ar, err := s.dao.GetUserByID(userID)
  260. // if err != nil {
  261. // utils.LogError(err.Error())
  262. // return nil, err
  263. // }
  264. // if ar == nil || ar.Status == models.STATUS_DEL {
  265. // return nil, errors.New("系统无该推荐人")
  266. // }
  267. // newCust.OrgId = ar.OrgId
  268. // newCust.RecommendId = ar.UserId
  269. // newCust.RecommendName = ar.RealName
  270. // }
  271. err = s.dao.UpdateCustomer(&newCust, []string{
  272. "phone",
  273. "name",
  274. "recommend_id",
  275. "recommend_case",
  276. "recommend_name",
  277. "binding_date",
  278. "barcode",
  279. })
  280. if err != nil {
  281. utils.LogError(err.Error())
  282. return nil, err
  283. }
  284. cust = &newCust
  285. // triggerRegiteEvent 触发注册事件
  286. // if cust.RecommendCase != "" {
  287. evtEngID := utils.EngineIDBy(customer.OrgId, "")
  288. evtEngine := utils.EventEngineBus(evtEngID)
  289. evtEngine.EmitEvent(events.EvtRegiste, *cust)
  290. // }
  291. // 如果客户ID 与映射表中一致, 说明已经绑定过了
  292. if cust.CustomerId == userMap.UserId {
  293. return cust, nil
  294. }
  295. // 更新用户映射信息
  296. userMap.UserId = cust.CustomerId
  297. if err := s.dao.UpdateUserMapping(userMap, []string{"user_id"}); err != nil {
  298. utils.LogError("更新用户映射信息失败:" + err.Error())
  299. return nil, errors.New("映射用户信息失败")
  300. }
  301. return cust, nil
  302. }
  303. // SaveNewCustomer 新增客户
  304. func (s *CustomerServ) SaveNewCustomer(wxInfo map[string]interface{}, caseID, arID, phone, userID string) (*model.TaCustomer, error) {
  305. // if caseID == "" && arID == "" && userID == "" {
  306. // return nil, errors.New("新增信息失败, 无法确认人员类型")
  307. // }
  308. // 微信相关字段
  309. nickyName := wxInfo["nickname"].(string)
  310. // sex := wxInfo["sex"].(string)
  311. var sexInt int
  312. switch val := wxInfo["sex"].(type) {
  313. case string:
  314. sexInt, _ = strconv.Atoi(val)
  315. case float64:
  316. sexInt = int(val)
  317. default:
  318. sexInt = 1
  319. }
  320. if sexInt == 0 {
  321. sexInt = 1 // 默认男性
  322. }
  323. headimgurl := wxInfo["headimgurl"].(string)
  324. org := s.ctx.Get("org").(model.SysOrg)
  325. cust := model.TaCustomer{
  326. CustomerName: nickyName,
  327. Name: nickyName,
  328. Sex: sexInt,
  329. Headimgurl: headimgurl,
  330. Phone: phone,
  331. OrgId: org.OrgId,
  332. }
  333. // 校验案场信息
  334. if caseID != "" {
  335. cs, err := s.casedao.GetCaseByID(caseID)
  336. if err != nil {
  337. utils.LogError(err.Error())
  338. return nil, err
  339. }
  340. if cs == nil || cs.Status == models.STATUS_DEL {
  341. return nil, errors.New("系统无该推荐案场")
  342. }
  343. cust.OrgId = cs.OrgId
  344. cust.RecommendCase = cs.CaseId
  345. }
  346. // 校验推荐人
  347. if arID != "" {
  348. ar, err := s.dao.GetUserByID(arID)
  349. if err != nil {
  350. utils.LogError(err.Error())
  351. return nil, err
  352. }
  353. if ar == nil || ar.Status == models.STATUS_DEL {
  354. return nil, errors.New("系统无该推荐人")
  355. }
  356. cust.OrgId = ar.OrgId
  357. cust.RecommendId = ar.UserId
  358. cust.RecommendName = ar.RealName
  359. }
  360. // 系统用户
  361. if userID != "" {
  362. user, err := s.dao.GetUserByID(userID)
  363. if err != nil {
  364. utils.LogError(err.Error())
  365. return nil, err
  366. }
  367. if user != nil && user.Status != models.STATUS_DEL {
  368. cust.CustomerId = userID
  369. }
  370. }
  371. if err := s.dao.SaveCustomer(&cust); err != nil {
  372. utils.LogError("更新客户信息失败: " + err.Error())
  373. return nil, errors.New("更新客户信息失败")
  374. }
  375. account := new(model.TaCustomerAccount)
  376. account.CustomerId = cust.CustomerId
  377. account.CustomerName = cust.CustomerName
  378. account.OrgId = cust.OrgId
  379. account.Amount = "0"
  380. account.Points = "0"
  381. account.PayedAmount = "0"
  382. account.PayedPoints = "0"
  383. if err := s.dao.SaveAccount(account); err != nil {
  384. utils.LogError("插入账户信息失败: " + err.Error())
  385. return nil, errors.New("更新客户信息失败")
  386. }
  387. return &cust, nil
  388. }
  389. // GetCustUserByTel 根据电话查询用户信息
  390. func (s *CustomerServ) GetCustUserByTel(tel string) (*model.TaCustomer, error) {
  391. customer, err := s.dao.GetCustomerByPhone(tel)
  392. if err != nil {
  393. return nil, err
  394. }
  395. return customer, nil
  396. }
  397. // GetCustomerInfo 获取客户个人信息
  398. func (s *CustomerServ) GetCustomerInfo() (map[string]interface{}, error) {
  399. customer := s.ctx.Get("customer").(model.TaCustomer)
  400. org := s.ctx.Get("org").(model.SysOrg)
  401. account, err := s.dao.GetAccountByCust(customer.CustomerId)
  402. if err != nil {
  403. utils.LogError("获取用户账户信息失败:", err)
  404. return nil, err
  405. }
  406. card, err := s.carddao.GetCustomerNoCardByCustomer(customer.CustomerId, org.OrgId)
  407. if err != nil {
  408. utils.LogError("获取用户卡信息失败:", err)
  409. return nil, err
  410. }
  411. coupon, err := s.coupondao.GetNoCouponByCustomer(org.OrgId, customer.CustomerId)
  412. if err != nil {
  413. utils.LogError("获取用户卡信息失败:", err)
  414. return nil, err
  415. }
  416. balance, err := s.dao.GetCustomerVipAmount(customer.CustomerId)
  417. return map[string]interface{}{
  418. "account": account,
  419. "cardsnum": len(card),
  420. "couponnum": len(coupon),
  421. "vipbalance": balance,
  422. }, nil
  423. }
  424. // EditUserMapping 更新用户map信息
  425. func (s *CustomerServ) EditUserMapping(userMap *model.TaUserMapping) (*model.TaUserMapping, error) {
  426. err := models.EditUserMapping(userMap)
  427. return userMap, err
  428. }