Message.php 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Description: 站内信
  4. // +----------------------------------------------------------------------
  5. // | Author: ymob
  6. // +----------------------------------------------------------------------
  7. namespace app\admin\model;
  8. use app\admin\model\ImportRecord as ImportRecordModel;
  9. use app\admin\model\User as UserModel;
  10. use app\crm\model\Contract as ContractModel;
  11. use app\crm\model\Invoice;
  12. use app\crm\model\Receivables as ReceivablesModel;
  13. use app\oa\model\Announcement as AnnouncementModel;
  14. use app\oa\model\Event as EventModel;
  15. use app\oa\model\Examine as ExamineModel;
  16. use app\oa\model\ExamineCategory;
  17. use app\oa\model\Log as LogModel;
  18. use app\work\model\Task as TaskModel;
  19. class Message extends Common
  20. {
  21. protected $name = 'admin_message';
  22. protected $autoWriteTimestamp = true;
  23. protected $createTime = 'send_time';
  24. protected $updateTime = false;
  25. /**
  26. * 错误信息
  27. */
  28. public $error = '';
  29. /**
  30. * 将要发送的消息内容
  31. */
  32. protected $content = '';
  33. /**
  34. * 消息类型
  35. */
  36. protected $type = 0;
  37. /**
  38. * 任务分配
  39. */
  40. const TASK_ALLOCATION = 1;
  41. /**
  42. * 任务邀请
  43. */
  44. const TASK_INVITE = 2;
  45. /**
  46. * 任务结束
  47. */
  48. const TASK_OVER = 3;
  49. /**
  50. * 回复日志
  51. */
  52. const LOG_REPLAY = 4;
  53. /**
  54. * 发送日志
  55. */
  56. const LOG_SEND = 5;
  57. /**
  58. * 审批待处理
  59. */
  60. const EXAMINE_TO_DO = 6;
  61. /**
  62. * 审批驳回
  63. */
  64. const EXAMINE_REJECT = 7;
  65. /**
  66. * 审批通过
  67. */
  68. const EXAMINE_PASS = 8;
  69. /**
  70. * 公告
  71. */
  72. const NOTICE_MESSAGE = 9;
  73. /**
  74. * 日程
  75. */
  76. const EVENT_MESSAGE = 10;
  77. /**
  78. * 合同待审批
  79. */
  80. const CONTRACT_TO_DO = 11;
  81. /**
  82. * 合同审批驳回
  83. */
  84. const CONTRACT_REJECT = 12;
  85. /**
  86. * 合同审批通过
  87. */
  88. const CONTRACT_PASS = 13;
  89. /**
  90. * 回款待审批
  91. */
  92. const RECEIVABLES_TO_DO = 14;
  93. /**
  94. * 回款审批驳回
  95. */
  96. const RECEIVABLES_REJECT = 15;
  97. /**
  98. * 回款审批通过
  99. */
  100. const RECEIVABLES_PASS = 16;
  101. /**
  102. * 客户导入
  103. */
  104. const IMPORT_CUSTOMER = 17;
  105. /**
  106. * 联系人
  107. */
  108. const IMPORT_CONTACTS = 18;
  109. /**
  110. * 线索
  111. */
  112. const IMPORT_LEADS = 19;
  113. /**
  114. * 产品
  115. */
  116. const IMPORT_PRODUCT = 20;
  117. /**
  118. * 团队成员-客户
  119. */
  120. const TEAM_CUSTOMER = 21;
  121. /**
  122. * 团队成员-商机
  123. */
  124. const TEAM_BUSINESS = 22;
  125. /**
  126. * 团队成员-合同
  127. */
  128. const TEAM_CONTRACT = 23;
  129. /**
  130. * 发票待审批
  131. */
  132. const INVOICE_TO_DO = 24;
  133. /**
  134. * 发票审批驳回
  135. */
  136. const INVOICE_REJECT = 25;
  137. /**
  138. * 发票审批通过
  139. */
  140. const INVOICE_PASS = 26;
  141. /**
  142. * 项目任务导入
  143. */
  144. const IMPORT_TASK = 27;
  145. /**
  146. * 退出商机团队
  147. */
  148. const BUSINESS_PASS = 28;
  149. /**
  150. * 退出客户团队
  151. */
  152. const CUSTOMER_PASS = 29;
  153. /**
  154. * 退出合同团队
  155. */
  156. const CONTRACT_END = 30;
  157. /**
  158. * 移除团队成员
  159. */
  160. const TEAM_END = 31;
  161. /**
  162. * 移除队成员
  163. */
  164. const TEAM_LEADS = 32;
  165. /**
  166. * 采购单待审批
  167. */
  168. const PURCHASE_TO_DO = 33;
  169. /**
  170. * 采购单审批驳回
  171. */
  172. const PURCHASE_REJECT = 34;
  173. /**
  174. * 采购单审批通过
  175. */
  176. const PURCHASE_PASS = 35;
  177. /**
  178. * 采购退货单待审批
  179. */
  180. const RETREAT_TO_DO = 36;
  181. /**
  182. * 采购退货单审批驳回
  183. */
  184. const RETREAT_REJECT = 37;
  185. /**
  186. * 采购退货单审批通过
  187. */
  188. const RETREAT_PASS = 38;
  189. /**
  190. * 销售订单待审批
  191. */
  192. const SALE_TO_DO = 39;
  193. /**
  194. * 销售订单审批驳回
  195. */
  196. const SALE_REJECT = 40;
  197. /**
  198. * 销售订单审批通过
  199. */
  200. const SALE_PASS = 41;
  201. /**
  202. * 销售退货单待审批
  203. */
  204. const SALERETURN_TO_DO = 42;
  205. /**
  206. * 销售退货单审批驳回
  207. */
  208. const SALERETURN_REJECT = 43;
  209. /**
  210. * 销售退货单审批通过
  211. */
  212. const SALERETURN_PASS = 44;
  213. /**
  214. * 回款单待审批
  215. */
  216. const COLLECTION_TO_DO = 45;
  217. /**
  218. * 回款单审批驳回
  219. */
  220. const COLLECTION_REJECT = 46;
  221. /**
  222. * 回款单审批通过
  223. */
  224. const COLLECTION_PASS = 47;
  225. /**
  226. * 付款单待审批
  227. */
  228. const PAYMENT_TO_DO = 48;
  229. /**
  230. * 付款单审批驳回
  231. */
  232. const PAYMENT_REJECT = 49;
  233. /**
  234. * 付款单审批通过
  235. */
  236. const PAYMENT_PASS = 50;
  237. /**
  238. * 调拨待审批
  239. */
  240. const ALLOCATION_TO_DO = 51;
  241. /**
  242. * 调拨审批驳回
  243. */
  244. const ALLOCATION_REJECT = 52;
  245. /**
  246. * 调拨审批通过
  247. */
  248. const ALLOCATION_PASS = 53;
  249. /**
  250. * 盘点待审批
  251. */
  252. const INVENTORY_TO_DO = 54;
  253. /**
  254. * 盘点审批驳回
  255. */
  256. const INVENTORY_REJECT = 55;
  257. /**
  258. * 盘点审批通过
  259. */
  260. const INVENTORY_PASS = 56;
  261. /**
  262. * 消息类型
  263. *
  264. * @var array
  265. * @author Ymob
  266. * @datetime 2019-10-17 15:27:43
  267. */
  268. protected $typeList = [
  269. 1 => [
  270. 'template' => '{from_user} 将 {title} 任务分配给您,请及时查看。',
  271. ],
  272. 2 => [
  273. 'template' => '{from_user} 邀请您参与 {title} 任务,请及时查看。',
  274. ],
  275. 3 => [
  276. 'template' => '{from_user} 将 {title} 任务标记结束。',
  277. ],
  278. 4 => [
  279. 'template' => '{from_user} 回复了您的 {title} 日志:“今天工作状态不错,继续加油!”,请及时查看',
  280. ],
  281. 5 => [
  282. 'template' => '{from_user} 将日志 {title} 发送给您,请及时查看。',
  283. ],
  284. 6 => [
  285. 'template' => '{from_user} 提交 {title} 审批,请及时处理。',
  286. ],
  287. 7 => [
  288. 'template' => '{from_user} 拒绝您的 {title} 审批,拒绝理由:“日期填写错误”,请及时处理。',
  289. ],
  290. 8 => [
  291. 'template' => '{from_user} 已经审核通过您的 {title} ,请及时查看。',
  292. ],
  293. 9 => [
  294. 'template' => '您有一个新公告 {title} ,请及时查看。',
  295. ],
  296. 10 => [
  297. 'template' => '{from_user} 邀请您参与 {title} 日程,将于**分钟后开始,请及时查看。',
  298. ],
  299. 11 => [
  300. 'template' => '{from_user} 提交 {title} 合同审批待您处理,请及时查看。',
  301. ],
  302. 12 => [
  303. 'template' => '{from_user} 拒绝您的 {title} 合同审批,拒绝理由:“日期填写错误”,请及时处理。',
  304. ],
  305. 13 => [
  306. 'template' => '{from_user} 已经审核通过您的 {title} 合同,请及时查看',
  307. ],
  308. 14 => [
  309. 'template' => '{from_user} 提交 {title} 回款审批待您处理,请及时查看。',
  310. ],
  311. 15 => [
  312. 'template' => '{from_user} 拒绝您的 {title} 回款审批,拒绝理由:“日期填写错误”,请及时处理。',
  313. ],
  314. 16 => [
  315. 'template' => '{from_user} 已经审核通过您的 {title} 回款,请及时查看。',
  316. ],
  317. 17 => [
  318. // 'template' => '{from_user} 导入客户数据,共 {total} 条,已导入 {done} 条 , 成功 {success} 条, 覆盖 {cover} 条, 失败 {error} 条。',
  319. 'template' => '{total},{cover},{success},{error}',
  320. ],
  321. 18 => [
  322. // 'template' => '{from_user} 导入联系人数据,共 {total} 条,已导入 {done} 条 , 成功 {success} 条, 覆盖 {cover} 条, 失败 {error} 条。',
  323. 'template' => '{total},{cover},{success},{error}',
  324. ],
  325. 19 => [
  326. // 'template' => '{from_user} 导入线索数据,共 {total} 条,已导入 {done} 条 , 成功 {success} 条, 覆盖 {cover} 条, 失败 {error} 条。',
  327. 'template' => '{total},{cover},{success},{error}',
  328. ],
  329. 20 => [
  330. // 'template' => '{from_user} 导入产品数据,共 {total} 条,已导入 {done} 条 , 成功 {success} 条, 覆盖 {cover} 条, 失败 {error} 条。',
  331. 'template' => '{total},{cover},{success},{error}',
  332. ],
  333. 21 => [
  334. 'template' => '{from_user} 将您添加为客户 {title} 的成员。',
  335. ],
  336. 22 => [
  337. 'template' => '{from_user} 将您添加为商机 {title} 的成员。',
  338. ],
  339. 23 => [
  340. 'template' => '{from_user} 将您添加为合同 {title} 的成员。',
  341. ],
  342. 24 => [
  343. 'template' => '{from_user} 提交 {title} 发票审批待您处理,请及时查看。',
  344. ],
  345. 25 => [
  346. 'template' => '{from_user} 拒绝您的 {title} 发票审批,请及时处理。',
  347. ],
  348. 26 => [
  349. 'template' => '您的 {title} 发票已经审批通过,请及时查看。',
  350. ],
  351. 27 => [
  352. // 'template' => '{date},{from_user} 导入任务,共 {total} 条,已导入 {done} 条 , 成功 {success} 条, 覆盖 {cover} 条, 失败 {error} 条。{title}',
  353. 'template' => '{total},{cover},{success},{error}',
  354. ],
  355. 28 => [
  356. 'template' => '{from_user} 退出了您商机 {title} 的团队。',
  357. ],
  358. 29 => [
  359. 'template' => '{from_user} 退出了您客户 {title} 的团队。',
  360. ],
  361. 30 => [
  362. 'template' => '{from_user} 退出了您合同 {title} 的团队。',
  363. ],
  364. 31 => [
  365. 'template' => '将{from_user} 移除了您 {title} 的团队。',
  366. ],
  367. 32 => [
  368. 'template' => '{from_user} 将您添加为线索 {title} 的成员。',
  369. ],
  370. ];
  371. /**
  372. * 消息类型分组
  373. */
  374. public static $typeGroup = [
  375. 'announcement' => [
  376. self::NOTICE_MESSAGE,
  377. ],
  378. 'examine' => [
  379. self::EXAMINE_TO_DO,
  380. self::EXAMINE_REJECT,
  381. self::EXAMINE_PASS,
  382. ],
  383. 'task' => [
  384. self::TASK_ALLOCATION,
  385. self::TASK_INVITE,
  386. self::TASK_OVER,
  387. self::IMPORT_TASK,
  388. ],
  389. 'log' => [
  390. self::LOG_REPLAY,
  391. self::LOG_SEND,
  392. ],
  393. 'event' => [
  394. self::EVENT_MESSAGE,
  395. ],
  396. 'crm' => [
  397. self::CONTRACT_TO_DO,
  398. self::CONTRACT_REJECT,
  399. self::CONTRACT_PASS,
  400. self::RECEIVABLES_TO_DO,
  401. self::RECEIVABLES_REJECT,
  402. self::RECEIVABLES_PASS,
  403. self::IMPORT_CUSTOMER,
  404. self::IMPORT_CONTACTS,
  405. self::IMPORT_LEADS,
  406. self::IMPORT_PRODUCT,
  407. self::TEAM_CUSTOMER,
  408. self::TEAM_BUSINESS,
  409. self::TEAM_CONTRACT,
  410. self::INVOICE_TO_DO,
  411. self::INVOICE_REJECT,
  412. self::INVOICE_PASS,
  413. self::BUSINESS_PASS,
  414. self::CUSTOMER_PASS,
  415. self::CONTRACT_END,
  416. ],
  417. 'jxc' => [
  418. self::PURCHASE_TO_DO,
  419. self::PURCHASE_REJECT,
  420. self::PURCHASE_PASS,
  421. self::RETREAT_TO_DO,
  422. self::RETREAT_REJECT,
  423. self::RETREAT_PASS,
  424. self::SALE_TO_DO,
  425. self::SALE_REJECT,
  426. self::SALE_PASS,
  427. self::SALERETURN_TO_DO,
  428. self::SALERETURN_REJECT,
  429. self::SALERETURN_PASS,
  430. self::COLLECTION_TO_DO,
  431. self::COLLECTION_REJECT,
  432. self::COLLECTION_PASS,
  433. self::PAYMENT_TO_DO,
  434. self::PAYMENT_REJECT,
  435. self::PAYMENT_PASS,
  436. self::ALLOCATION_TO_DO,
  437. self::ALLOCATION_REJECT,
  438. self::ALLOCATION_PASS,
  439. self::INVENTORY_TO_DO,
  440. self::INVENTORY_REJECT,
  441. self::INVENTORY_PASS,
  442. ]
  443. ];
  444. /**
  445. * 发送系统通知
  446. *
  447. * @param int $type 消息类型
  448. * @param array $data 关联信息
  449. * @param array|int $user_id 接收消息员工ID
  450. * @param boolean $system 是否系统消息
  451. * @return bool
  452. * @author Ymob
  453. * @datetime 2019-10-17 17:23:05
  454. */
  455. public function send($type, $data, $user_id_list, $system = false)
  456. {
  457. if (!isset($this->typeList[$type])) {
  458. $this->error = '消息类型错误';
  459. return false;
  460. }
  461. $user_id_list = (array)$user_id_list;
  462. $user_id_list = array_unique(array_filter($user_id_list));
  463. if (empty($user_id_list)) {
  464. $this->error = '接收人不能为空';
  465. return false;
  466. }
  467. $action_id = $data['action_id'];
  468. $title = $data['title'];
  469. $content = $this->typeList[$type]['template'];
  470. foreach ($data as $key => $val) {
  471. $content = str_replace('{' . $key . '}', $val, $content);
  472. }
  473. $advance_time= $data['advance_time'];
  474. $content = str_replace('{from_user}', User::userInfo('realname'), $content);
  475. $content = str_replace('{date}', date('Y-m-d'), $content);
  476. $data = [];
  477. $data['type'] = $type;
  478. $data['content'] = $content;
  479. $data['action_id'] = $action_id;
  480. $data['read_time'] = 0;
  481. $data['from_user_id'] = $system ? 0 : User::userInfo('id');
  482. $data['title'] = $title;
  483. $data['advance_time'] = $advance_time ?: 0;
  484. $request = request();
  485. $data['controller_name'] = strtolower($request->controller());
  486. $data['module_name'] = strtolower($request->module());
  487. $data['action_name'] = strtolower($request->action());
  488. $from_user_id = $data['from_user_id'];
  489. if (!in_array($type,[9,17,18,19,20,27])) {
  490. $user_id_list = array_filter($user_id_list, function ($val) use ($from_user_id) {
  491. return $val !== $from_user_id;
  492. });
  493. }
  494. $all_data = [];
  495. foreach ($user_id_list as $user_id) {
  496. $temp = $data;
  497. $temp['to_user_id'] = $user_id;
  498. $all_data[] = $temp;
  499. }
  500. if (!empty($from_user_id) && class_exists('DingTalk')) {
  501. (new Dingtalk())->message($user_id_list, $content);
  502. }
  503. $this->saveAll($all_data);
  504. }
  505. /**
  506. * 获取关联模块数据
  507. *
  508. * @author Ymob
  509. * @datetime 2019-10-22 15:34:35
  510. */
  511. public function getRelationTitleAttr($val, $data)
  512. {
  513. switch ($data['type']) {
  514. // 任务
  515. case self::TASK_ALLOCATION:
  516. case self::TASK_INVITE:
  517. case self::TASK_OVER:
  518. return TaskModel::where(['task_id' => $data['action_id']])->value('name') ?: '';
  519. // 日志
  520. case self::LOG_REPLAY:
  521. case self::LOG_SEND:
  522. return LogModel::where(['log_id' => $data['action_id']])->value('title') ?: '';
  523. // 审批
  524. case self::EXAMINE_TO_DO:
  525. case self::EXAMINE_REJECT:
  526. case self::EXAMINE_PASS:
  527. $category_id = ExamineModel::where(['examine_id' => $data['action_id']])->value('category_id') ?: 0;
  528. $categoryInfo = (new ExamineCategory())->getDataById($category_id);
  529. return $categoryInfo['title'];
  530. // 公告
  531. case self::NOTICE_MESSAGE:
  532. return AnnouncementModel::where(['announcement_id' => $data['action_id']])->value('title') ?: '';
  533. // 日程
  534. case self::EVENT_MESSAGE:
  535. return EventModel::where(['event_id' => $data['action_id']])->value('title') ?: '';
  536. // 合同
  537. case self::CONTRACT_TO_DO:
  538. case self::CONTRACT_REJECT:
  539. case self::CONTRACT_PASS:
  540. case self::TEAM_CONTRACT:
  541. return ContractModel::where(['contract_id' => $data['action_id']])->value('name') ?: '';
  542. // 回款
  543. case self::RECEIVABLES_TO_DO:
  544. case self::RECEIVABLES_REJECT:
  545. case self::RECEIVABLES_PASS:
  546. return ReceivablesModel::where(['receivables_id' => $data['action_id']])->value('number') ?: '';
  547. // 发票
  548. case self::INVOICE_TO_DO:
  549. case self::INVOICE_REJECT:
  550. case self::INVOICE_PASS:
  551. return Invoice::where(['invoice_id' => $data['action_id']])->value('invoice_apple_number') ?: '';
  552. // 导入数据
  553. case self::IMPORT_CUSTOMER:
  554. case self::IMPORT_CONTACTS:
  555. case self::IMPORT_LEADS:
  556. case self::IMPORT_PRODUCT:
  557. case self::IMPORT_TASK:
  558. $error = ImportRecordModel::where(['id' => $data['action_id']])->value('error');
  559. return $error ? '点击下载错误数据' : '';
  560. // 客户
  561. case self::TEAM_CUSTOMER:
  562. case self::CUSTOMER_PASS:
  563. return CustomerModel::where(['customer_id' => $data['action_id']])->value('name') ?: '';
  564. // 商机
  565. case self::TEAM_BUSINESS:
  566. case self::BUSINESS_PASS:
  567. return BusinessModel::where(['business_id' => $data['action_id']])->value('name') ?: '';
  568. // 采购单
  569. case self::PURCHASE_TO_DO:
  570. case self::PURCHASE_REJECT:
  571. case self::PURCHASE_PASS:
  572. return PurchaseModel::where(['purchase_id' => $data['action_id']])->value('order_number') ?: '';
  573. // 采购退货单
  574. case self::RETREAT_TO_DO:
  575. case self::RETREAT_REJECT:
  576. case self::RETREAT_PASS:
  577. return RetreatModel::where(['retreat_id' => $data['action_id']])->value('order_number') ?: '';
  578. // 销售订单
  579. case self::SALE_TO_DO:
  580. case self::SALE_REJECT:
  581. case self::SALE_PASS:
  582. return SaleModel::where(['sale_id' => $data['action_id']])->value('order_number') ?: '';
  583. // 销售退货单订单
  584. case self::SALERETURN_TO_DO:
  585. case self::SALERETURN_REJECT:
  586. case self::SALERETURN_PASS:
  587. return SalereturnModel::where(['salereturn_id' => $data['action_id']])->value('order_number') ?: '';
  588. // 回款单
  589. case self::COLLECTION_TO_DO:
  590. case self::COLLECTION_REJECT:
  591. case self::COLLECTION_PASS:
  592. return CollectionModel::where(['collection_note_id' => $data['action_id']])->value('collection_no') ?: '';
  593. // 付款单
  594. case self::PAYMENT_TO_DO:
  595. case self::PAYMENT_REJECT:
  596. case self::PAYMENT_PASS:
  597. return PaymentModel::where(['payment_note_id' => $data['action_id']])->value('payment_no') ?: '';
  598. // 调拨
  599. case self::ALLOCATION_TO_DO:
  600. case self::ALLOCATION_REJECT:
  601. case self::ALLOCATION_PASS:
  602. return PaymentModel::where(['allocation_id' => $data['action_id']])->value('allocation_code') ?: '';
  603. // 盘点
  604. case self::INVENTORY_TO_DO:
  605. case self::INVENTORY_REJECT:
  606. case self::INVENTORY_PASS:
  607. return PaymentModel::where(['inventory_id' => $data['action_id']])->value('inventory_number') ?: '';
  608. }
  609. return '';
  610. }
  611. /**
  612. * 发送人
  613. */
  614. public function getFromUserIdInfoAttr($val, $data)
  615. {
  616. return $data['from_user_id'] ? UserModel::getUserById($data['from_user_id']) : [];
  617. }
  618. }