ActivityLogic.php 33KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. <?php
  2. /**
  3. * 活动逻辑类
  4. *
  5. * @author qifan
  6. * @date 2020-12-09
  7. */
  8. namespace app\crm\logic;
  9. use app\admin\model\Group;
  10. use app\crm\model\Activity;
  11. use think\Db;
  12. class ActivityLogic
  13. {
  14. # 活动类型 1 线索 2 客户 3 联系人 4 产品 5 商机 6 合同 7 回款 8 日志 9 审批 10 日程 11 任务 12 发邮件
  15. private $activityType = [
  16. 1 => ['en' => 'crm_leads', 'cn' => '线索'],
  17. 2 => ['en' => 'crm_customer', 'cn' => '客户'],
  18. 3 => ['en' => 'crm_contacts', 'cn' => '联系人'],
  19. 4 => ['en' => 'crm_product', 'cn' => '产品'],
  20. 5 => ['en' => 'crm_business', 'cn' => '商机'],
  21. 6 => ['en' => 'crm_contract', 'cn' => '合同'],
  22. 7 => ['en' => 'crm_receivables', 'cn' => '回款'],
  23. 8 => ['en' => 'oa_log', 'cn' => '日志'],
  24. 9 => ['en' => 'oa_examine', 'cn' => '审批'],
  25. 10 => ['en' => 'oa_event', 'cn' => '日程'],
  26. 11 => ['en' => 'oa_task', 'cn' => '任务'],
  27. 12 => ['en' => 'mail', 'cn' => '发邮件']
  28. ];
  29. private $moduleToNumber = [
  30. 'leads' => 1,
  31. 'customer' => 2,
  32. 'contacts' => 3,
  33. 'product' => 4,
  34. 'business' => 5,
  35. 'contract' => 6,
  36. 'receivables' => 7,
  37. 'log' => 8,
  38. 'examine' => 9,
  39. 'event' => 10,
  40. 'task' => 11,
  41. 'email' => 12
  42. ];
  43. /**
  44. * 活动列表
  45. *
  46. * @param $param
  47. * @return array
  48. * @throws \think\db\exception\DataNotFoundException
  49. * @throws \think\db\exception\ModelNotFoundException
  50. * @throws \think\exception\DbException
  51. */
  52. public function index($param)
  53. {
  54. $userId = $param['user_id'];
  55. unset($param['user_id']);
  56. unset($param['crmType']);
  57. $param['limit'] = !empty($param['limit']) ? $param['limit'] : 15;
  58. $param['page'] = !empty($param['page']) ? $param['page'] : 1;
  59. $recordWhere = [];
  60. $commonWhere = [];
  61. $leadsWhere = [];
  62. $customerWhere = function () {};
  63. $contactsWhere = function () {};
  64. $businessWhere = function () {};
  65. $contractWhere = function () {};
  66. $dateGroupWhere = function () {};
  67. # 跟进记录权限判断
  68. if (!checkPerByAction('crm', 'activity', 'index')) {
  69. $recordWhere['type'] = ['neq', 1];
  70. }
  71. # 设置时间分组查询条件,第一页就是当天的数据,第二页就是下一天的数据
  72. $datetime = Db::name('crm_activity')
  73. ->field('update_time')
  74. ->where($recordWhere)
  75. ->where('status', 1)
  76. ->where(function ($query) use ($param) {
  77. $query->whereOr(function ($query) use ($param) {
  78. $query->where('activity_type_id', $param['activity_type_id']);
  79. $query->where('activity_type', $this->moduleToNumber[$param['module']]);
  80. });
  81. $query->whereOr('customer_ids', 'like', ',%'.$param['activity_type_id'].'%,');
  82. $query->whereOr('contacts_ids', 'like', ',%'.$param['activity_type_id'].'%,');
  83. $query->whereOr('contract_ids', 'like', ',%'.$param['activity_type_id'].'%,');
  84. $query->whereOr('business_ids', 'like', ',%'.$param['activity_type_id'].'%,');
  85. $query->whereOr('leads_ids', 'like', ',%'.$param['activity_type_id'].'%,');
  86. })
  87. ->order('update_time', 'desc')
  88. ->group('update_time')
  89. ->select();
  90. $dateGroup = [0 => '']; // 加一个占位,page是从1开始
  91. $dateWhere = [0 => []]; // 加一个占位,page是从1开始
  92. foreach ($datetime AS $key => $value) {
  93. $date = date('Y-m-d', $value['update_time']);
  94. if (!in_array($date, $dateGroup)) {
  95. $dateGroup[] = $date;
  96. $dateWhere[] = [
  97. 'start_time' => strtotime($date . ' 00:00:00'),
  98. 'end_time' => strtotime($date . ' 23:59:59')
  99. ];
  100. }
  101. }
  102. if (!empty($dateWhere[$param['page']])) {
  103. $dateGroupWhere = function ($query) use ($param, $dateWhere) {
  104. $query->where('update_time', '>=', $dateWhere[$param['page']]['start_time']);
  105. $query->where('update_time', '<=', $dateWhere[$param['page']]['end_time']);
  106. };
  107. }
  108. if (empty($dateWhere[$param['page']])) {
  109. return ['lastPage' => true, 'list' => [], 'time' => ''];
  110. }
  111. # 处理公共查询参数
  112. if (!empty($param['interval_day'])) {
  113. $commonWhere['update_time'] = ['egt', time() - 86400 * $param['interval_day']];
  114. $commonWhere['update_time'] = ['elt', time()];
  115. }
  116. if (!empty($param['start_date']) && !empty($param['end_date'])) {
  117. $commonWhere['update_time'] = ['egt', strtotime($param['start_date'])];
  118. $commonWhere['update_time'] = ['elt', strtotime($param['end_date'])];
  119. }
  120. if (!empty($param['search'])) {
  121. $commonWhere['content'] = ['like', '%' . $param['search'] . '%'];
  122. }
  123. if (!empty($param['activity_type'])) {
  124. $commonWhere['activity_type'] = $param['activity_type'];
  125. }
  126. # 组织线索、客户、联系人、商机、合同下的查询条件
  127. switch ($param['module']) {
  128. case 'leads' :
  129. $leadsWhere = function ($query) use ($param) {
  130. $query->where('activity_type', 1);
  131. $query->where('activity_type_id', $param['activity_type_id']);
  132. };
  133. break;
  134. case 'customer' :
  135. $contactsData = [];
  136. $businessData = [];
  137. $contractData = [];
  138. $receivablesData = [];
  139. # 联系人ID串
  140. $contacts = Db::name('crm_contacts')->field(['contacts_id'])->where('customer_id', $param['activity_type_id'])->select();
  141. if (!empty($contacts)) {
  142. $contactsData['activity_type'] = 3;
  143. $contactsData['activity_type_id'] = array_reduce($contacts, function ($result, $value) {
  144. return array_merge($result, array_values($value));
  145. }, []);
  146. }
  147. # 商机ID串
  148. $business = Db::name('crm_business')->field(['business_id'])->where('customer_id', $param['activity_type_id'])->select();
  149. if (!empty($business)) {
  150. $businessData['activity_type'] = 5;
  151. $businessData['activity_type_id'] = array_reduce($business, function ($result, $value) {
  152. return array_merge($result, array_values($value));
  153. }, []);
  154. }
  155. # 合同ID串
  156. $contract = Db::name('crm_contract')->field(['contract_id'])->where('customer_id', $param['activity_type_id'])->select();
  157. if (!empty($contract)) {
  158. $contractData['activity_type'] = 6;
  159. $contractData['activity_type_id'] = array_reduce($contract, function ($result, $value) {
  160. return array_merge($result, array_values($value));
  161. }, []);
  162. }
  163. # 回款ID串
  164. $receivables = Db::name('crm_receivables')->field(['receivables_id'])->where('customer_id', $param['activity_type_id'])->select();
  165. if (!empty($receivables)) {
  166. $receivablesData['activity_type'] = 7;
  167. $receivablesData['activity_type_id'] = array_reduce($receivables, function ($result, $value) {
  168. return array_merge($result, array_values($value));
  169. }, []);
  170. }
  171. # 客户模块查询条件
  172. $customerWhere = function ($query) use ($param, $contactsData, $businessData, $contractData, $receivablesData) {
  173. $query->whereOr(function ($query) use ($param) {
  174. $query->where('activity_type', 2);
  175. $query->where('activity_type_id', $param['activity_type_id']);
  176. });
  177. $query->whereOr(function ($query) use ($param) {
  178. $query->where('customer_ids', 'like', '%,' . $param['activity_type_id'] . ',%');
  179. $query->whereIn('activity_type', [8, 9, 11]);
  180. });
  181. if (!empty($contactsData)) {
  182. $query->whereOr(function ($query) use ($contactsData) {
  183. $query->where('activity_type', $contactsData['activity_type']);
  184. $query->whereIn('activity_type_id', $contactsData['activity_type_id']);
  185. });
  186. }
  187. if (!empty($businessData)) {
  188. $query->whereOr(function ($query) use ($businessData) {
  189. $query->where('activity_type', $businessData['activity_type']);
  190. $query->whereIn('activity_type_id', $businessData['activity_type_id']);
  191. });
  192. }
  193. if (!empty($contractData)) {
  194. $query->whereOr(function ($query) use ($contractData) {
  195. $query->where('activity_type', $contractData['activity_type']);
  196. $query->whereIn('activity_type_id', $contractData['activity_type_id']);
  197. });
  198. }
  199. if (!empty($receivablesData)) {
  200. $query->whereOr(function ($query) use ($receivablesData) {
  201. $query->where('activity_type', $receivablesData['activity_type']);
  202. $query->whereIn('activity_type_id', $receivablesData['activity_type_id']);
  203. });
  204. }
  205. };
  206. break;
  207. case 'contacts' :
  208. # 联系人模块查询条件
  209. $contactsWhere = function ($query) use ($param) {
  210. $query->whereOr(function ($query) use ($param) {
  211. $query->where('activity_type', 3);
  212. $query->where('activity_type_id', $param['activity_type_id']);
  213. });
  214. $query->whereOr(function ($query) use ($param) {
  215. $query->where('contacts_ids', 'like', '%,' . $param['activity_type_id'] . ',%');
  216. $query->whereIn('activity_type', [8, 9, 11]);
  217. });
  218. };
  219. break;
  220. case 'business' :
  221. # 商机模块查询条件
  222. $businessWhere = function ($query) use ($param) {
  223. $query->whereOr(function ($query) use ($param) {
  224. $query->where('activity_type', 5);
  225. $query->where('activity_type_id', $param['activity_type_id']);
  226. });
  227. $query->whereOr(function ($query) use ($param) {
  228. $query->where('business_ids', 'like', '%,' . $param['activity_type_id'] . ',%');
  229. $query->whereIn('activity_type', [8, 9, 11]);
  230. });
  231. };
  232. break;
  233. case 'contract' :
  234. # 合同模块查询条件
  235. $contractWhere = function ($query) use ($param) {
  236. $query->whereOr(function ($query) use ($param) {
  237. $query->where('activity_type', 6);
  238. $query->where('activity_type_id', $param['activity_type_id']);
  239. });
  240. $query->whereOr(function ($query) use ($param) {
  241. $query->where('contract_ids', 'like', '%,' . $param['activity_type_id'] . ',%');
  242. $query->whereIn('activity_type', [8, 9, 11]);
  243. });
  244. };
  245. break;
  246. }
  247. $field = [
  248. 'activity_id',
  249. 'type',
  250. 'category',
  251. 'activity_type',
  252. 'activity_type_id',
  253. 'content',
  254. 'contacts_ids',
  255. 'next_time',
  256. 'create_user_id',
  257. 'update_time',
  258. 'business_ids'
  259. ];
  260. $dataArray = Db::name('crm_activity')->field($field)
  261. ->where($dateGroupWhere)
  262. ->where($recordWhere)
  263. ->where($commonWhere)
  264. ->where($customerWhere)
  265. ->where($contactsWhere)
  266. ->where($businessWhere)
  267. ->where($contractWhere)
  268. ->where($leadsWhere)
  269. ->where('status', 1)
  270. ->order('update_time', 'desc')
  271. ->select();
  272. $fileModel = new \app\admin\model\File();
  273. foreach ($dataArray AS $key => $value) {
  274. # 用户信息 todo 有模型文件,时间问题,暂时将查询写在循环中
  275. $realname = Db::name('admin_user')->where('id', $dataArray[$key]['create_user_id'])->find();
  276. $dataArray[$key]['create_user_name'] = $realname['realname'];
  277. $dataArray[$key]['thumb_img'] = $realname['thumb_img'] ? getFullPath($realname['thumb_img']) : '';;
  278. # 附件信息
  279. if ($value['type'] = 1) {
  280. $files = [];
  281. $images = [];
  282. $fileList = $fileModel->getDataList(['module' => 'crm_activity', 'module_id' => $dataArray[$key]['activity_id']], 'all');
  283. if (!empty($fileList['list'])) {
  284. foreach ($fileList['list'] AS $k => $v) {
  285. if ($v['types'] == 'file') {
  286. $files[] = $v;
  287. } else {
  288. $images[] = $v;
  289. }
  290. }
  291. }
  292. $dataArray[$key]['fileList'] = $files ? : [];
  293. $dataArray[$key]['imgList'] = $images ? : [];
  294. }
  295. # 判断是不是本人添加的,如果不是将禁止删除修改
  296. $dataArray[$key]['auth'] = false;
  297. if ($dataArray[$key]['type'] == 1 && $dataArray[$key]['create_user_id'] == $userId) {
  298. $dataArray[$key]['auth'] = true;
  299. }
  300. # 查询联系人信息
  301. $dataArray[$key]['contacts_list'] = [];
  302. if ($dataArray[$key]['type'] == 1 && !empty($dataArray[$key]['contacts_ids'])) {
  303. $res = Db::name('crm_contacts')->where('contacts_id', trim($dataArray[$key]['contacts_ids'], ','))->value('name');
  304. $dataArray[$key]['contacts_list'][] = [
  305. 'contacts_id' => (int)trim($dataArray[$key]['contacts_ids'], ','),
  306. 'name' =>empty($res)? null : $res,
  307. ];
  308. }
  309. # 时间格式处理
  310. $dataArray[$key]['update_time'] = date('Y-m-d H:i:s', $value['update_time']);
  311. $dataArray[$key]['create_time'] = date('Y-m-d H:i:s', $value['create_time']);
  312. $dataArray[$key]['next_time'] = !empty($value['next_time']) ? date('Y-m-d H:i:s', $value['next_time']) : '';
  313. # 获取类型名称
  314. $dataArray[$key]['activity_type_name'] = $this->getActivityName($value['activity_type'], $value['activity_type_id']);
  315. # 客户模块跟进记录关联的商机
  316. $dataArray[$key]['business_list'] = $value['activity_type'] == 2 ? $this->getBusinessInfo($value['business_ids']) : [];
  317. # 去掉客户模块跟进记录联系人ID两端的逗号
  318. if ($value['type'] == 1 && $value['activity_type'] == 2) {
  319. $dataArray[$key]['contacts_ids'] = !empty($value['contacts_ids']) ? trim($value['contacts_ids'], ',') : '';
  320. }
  321. }
  322. # 是否是最后一页
  323. $lastPage = !empty($dateGroup[$param['page']]) && $param['page'] < count($dateGroup) - 1 ? false : true;
  324. return ['lastPage' => $lastPage, 'list' => $dataArray, 'time' => !empty($dateGroup[$param['page']]) ? $dateGroup[$param['page']] : ''];
  325. }
  326. /**
  327. * 活动详情【跟进记录】
  328. *
  329. * @param $activityId
  330. * @return array|bool|\PDOStatement|string|\think\Model|null
  331. * @throws \think\db\exception\DataNotFoundException
  332. * @throws \think\db\exception\ModelNotFoundException
  333. * @throws \think\exception\DbException
  334. */
  335. public function read($activityId)
  336. {
  337. # 查询跟进记录信息
  338. $field = ['activity_id', 'category', 'activity_type', 'activity_type_id', 'content', 'next_time', 'customer_ids', 'contacts_ids', 'contract_ids', 'business_ids'];
  339. $activityData = Activity::field($field)->where('type', 1)->where('activity_id', $activityId)->where('status', 1)->find();
  340. if (empty($activityData)) return [];
  341. # 查询与跟进记录关联的客户信息
  342. $customerData = Db::name('crm_customer')->field(['customer_id', 'name'])->whereIn('customer_id', $activityData['customer_ids'])->select();
  343. $activityData['customerInfo'] = $customerData;
  344. # 查询与跟进记录关联的联系人信息
  345. $contactsData = Db::name('crm_contacts')->field(['contacts_id', 'name'])->whereIn('contacts_id', $activityData['contacts_ids'])->select();
  346. $activityData['contactsInfo'] = $contactsData;
  347. # 查询与跟进记录关联的合同信息
  348. $contractData = Db::name('crm_contract')->field(['contract_id', 'name'])->whereIn('contract_id', $activityData['contract_ids'])->select();
  349. $activityData['contractInfo'] = $contractData;
  350. # 查询与跟进记录关联的商机信息
  351. $businessData = Db::name('crm_business')->field(['business_id', 'name'])->whereIn('business_id', $activityData['business_ids'])->select();
  352. $activityData['businessInfo'] = $businessData;
  353. # 查询与跟进记录关联的附件
  354. $fileData = (new \app\admin\model\File())->getDataList(['module' => 'crm_activity', 'module_id' => $activityId], 'all');
  355. $activityData['fileInfo'] = $fileData;
  356. return $activityData;
  357. }
  358. /**
  359. * 创建活动【跟进记录】
  360. *
  361. * @param $param
  362. * @return bool
  363. * @throws \think\Exception
  364. * @throws \think\exception\PDOException
  365. */
  366. public function save($param)
  367. {
  368. $userId = $param['user_id'];
  369. $isEvent = !empty($param['is_event']) ? $param['is_event'] : 0;
  370. $fileIds = !empty($param['file_id']) ? $param['file_id'] : [];
  371. unset($param['is_event']);
  372. unset($param['file_id']);
  373. unset($param['user_id']);
  374. $param['create_user_id'] = $userId;
  375. $param['type'] = 1;
  376. $param['next_time'] = !empty($param['next_time']) ? strtotime($param['next_time']) : 0;
  377. $param['business_ids'] = !empty($param['business_ids']) ? arrayToString($param['business_ids']) : '';
  378. $param['create_time'] = time();
  379. $param['update_time'] = time();
  380. if (!empty($param['contacts_ids'])) $param['contacts_ids'] = ',' . $param['contacts_ids'] . ',';
  381. $activityJson = Activity::create($param);
  382. if (empty($activityJson)) return false;
  383. $activityArray = json_decode($activityJson, true);
  384. if (empty($activityArray['activity_id'])) return false;
  385. # 设置最后跟进记录
  386. $this->setFollowRecord($param['activity_type'], $param['activity_type_id'], $param['content']);
  387. # 下次联系时间
  388. $this->updateNextTime($this->activityType[$param['activity_type']]['en'], $param['activity_type_id'], $param['next_time'],false);
  389. # 处理附件关系
  390. if (!empty($fileIds)) {
  391. $fileModel = new \app\admin\model\File();
  392. $fileModel->createDataById($fileIds, 'crm_activity', $activityArray['activity_id']);
  393. }
  394. # 同时创建日程
  395. if ($isEvent) {
  396. $eventModel = new \app\oa\model\Event();
  397. $data['title'] = trim($param['content']);
  398. $data['content'] = trim($param['content']);
  399. $data['start_time'] = !empty($param['next_time']) ? $param['next_time'] : time();
  400. $data['end_time'] = $param['next_time'] + 86399;
  401. $data['create_user_id'] = $param['create_user_id'];
  402. $data['business_ids'] = $param['business_ids'];
  403. $data['contacts_ids'] = $param['contacts_ids'];
  404. $data['is_live'] = true;
  405. if ($param['activity_type'] == 'crm_customer') $data['customer_ids'] = $param['activity_type_id'];
  406. $eventModel->createData($data);
  407. }
  408. return true;
  409. }
  410. /**
  411. * 修改活动【跟进记录】
  412. *
  413. * @param $param
  414. * @return bool
  415. * @throws \think\Exception
  416. * @throws \think\exception\PDOException
  417. */
  418. public function update($param)
  419. {
  420. $isEvent = !empty($param['is_event']) ? $param['is_event'] : 0;
  421. $fileIds = !empty($param['file_id']) ? $param['file_id'] : [];
  422. unset($param['is_event']);
  423. unset($param['file_id']);
  424. $param['type'] = 1;
  425. $param['next_time'] = strtotime($param['next_time']);
  426. $param['business_ids'] = !empty($param['business_ids']) ? arrayToString($param['business_ids']) : '';
  427. $param['update_time'] = time();
  428. if (!Activity::update($param)) return false;
  429. # 设置最后跟进记录
  430. $this->setFollowRecord($param['activity_type'], $param['activity_type_id'], $param['content']);
  431. # 下次联系时间
  432. $this->updateNextTime($this->activityType[$param['activity_type']]['en'], $param['activity_type_id'], $param['next_time'],false);
  433. # 处理附件关系
  434. $fileModel = new \app\admin\model\File();
  435. if (!empty($fileIds)) {
  436. # 删除
  437. $fileModel->delRFileByModule('crm_activity', $param['activity_id']);
  438. # 添加
  439. $fileModel->createDataById($fileIds, 'crm_activity', $param['activity_id']);
  440. } else {
  441. # 删除
  442. $fileModel->delRFileByModule('crm_activity', $param['activity_id']);
  443. }
  444. # 同时创建日程
  445. if ($isEvent) {
  446. $eventModel = new \app\oa\model\Event();
  447. $data['title'] = trim($param['content']);
  448. $data['content'] = trim($param['content']);
  449. $data['start_time'] = !empty($param['next_time']) ? $param['next_time'] : time();
  450. $data['end_time'] = $param['next_time'] + 86399;
  451. $data['create_user_id'] = $param['create_user_id'];
  452. $data['business_ids'] = $param['business_ids'];
  453. $data['contacts_ids'] = $param['contacts_ids'];
  454. if ($param['activity_type'] == 2) $data['customer_ids'] = $param['activity_type_id'];
  455. $eventModel->createData($data);
  456. }
  457. return true;
  458. }
  459. /**
  460. * 删除活动【跟进记录】
  461. *
  462. * @param $activityId
  463. * @return Activity
  464. */
  465. public function delete($activityId)
  466. {
  467. $activityInfo = Db::name('crm_activity')->where(['activity_id' => $activityId])->find();
  468. if (Activity::update(['activity_id' => $activityId, 'status' => 0])) {
  469. $this->updateNextTime($this->activityType[$activityInfo['activity_type']]['en'], $activityInfo['activity_type_id'], '', true);
  470. # 删除附件
  471. $fileIds = db('crm_activity_file')->where('activity_id', $activityId)->column('file_id');
  472. if (!empty($fileIds)) {
  473. db('crm_activity_file')->where('activity_id', $activityId)->delete();
  474. db('admin_file')->whereIn('file_id', $fileIds)->delete();
  475. }
  476. if ($activityInfo['activity_type'] == 3) db('crm_contacts_file')->whereIn('file_id', $fileIds)->delete();
  477. if ($activityInfo['activity_type'] == 5) db('crm_business_file')->whereIn('file_id', $fileIds)->delete();
  478. if ($activityInfo['activity_type'] == 6) db('crm_contract_file')->whereIn('file_id', $fileIds)->delete();
  479. return true;
  480. } else {
  481. return false;
  482. }
  483. }
  484. /**
  485. * 相关模块下次联系时间
  486. *
  487. * @param $types
  488. * @param $types_id
  489. * @param string $next_time
  490. * @return bool
  491. * @throws \think\Exception
  492. * @throws \think\exception\PDOException
  493. */
  494. private function updateNextTime($types, $types_id, $next_time = '', $is_del = false)
  495. {
  496. switch ($types) {
  497. case 'crm_customer' : $dbName = db('crm_customer'); $dbId = 'customer_id'; $activity_type = 2; break;
  498. case 'crm_leads' : $dbName = db('crm_leads'); $dbId = 'leads_id'; $activity_type = 1; break;
  499. case 'crm_contacts' : $dbName = db('crm_contacts'); $dbId = 'contacts_id'; $activity_type = 3; break;
  500. case 'crm_business' : $dbName = db('crm_business'); $dbId = 'business_id'; $activity_type = 5; break;
  501. default : break;
  502. }
  503. if (!$dbName || !$dbId) return true;
  504. $data = [];
  505. $data['update_time'] = time();
  506. if (!empty($next_time)) {
  507. $data['next_time'] = $next_time;
  508. } else {
  509. if ($is_del) {
  510. # 查找最近一条下次联系时间补上,如果没有就置空
  511. $resActivity = Db::name('crm_activity')->where(['type'=>1, 'activity_type'=>$activity_type, 'activity_type_id' => $types_id,'status'=>['neq',0]])->order('activity_id desc')->find();
  512. $data['next_time'] = $resActivity['next_time'] ? : 0;
  513. unset($data['update_time']);
  514. } else {
  515. # 如果未填写下次联系时间,并且 原下次联系时间为当天,则把下次联系时间置空
  516. $next_time = $dbName->where([$dbId => $types_id])->value('next_time');
  517. list($start, $end) = getTimeByType();
  518. if ($next_time >= $start && $next_time <= $end) {
  519. $data['next_time'] = 0;
  520. }
  521. }
  522. }
  523. if (!$is_del && in_array($types, ['crm_customer', 'crm_leads'])) {
  524. $data['follow'] = '已跟进';
  525. }
  526. # 设置今日需联系线索、客户、商机
  527. if (!$is_del && in_array($types, ['crm_customer', 'crm_leads', 'crm_business'])) {
  528. if (!empty($next_time) && $next_time >= strtotime('Y-m-d 00:00:00')) $data['is_dealt'] = 0;
  529. }
  530. $dbName->where([$dbId => $types_id])->update($data);
  531. return true;
  532. }
  533. /**
  534. * 获取常用语
  535. *
  536. * @return mixed
  537. */
  538. public function getPhrase()
  539. {
  540. $dataJson = Db::name('crm_config')->where('name', 'activity_phrase')->value('value');
  541. return !empty($dataJson) ? unserialize($dataJson) : [];
  542. }
  543. /**
  544. * 设置常用语
  545. *
  546. * @param $param
  547. * @return int|string
  548. * @throws \think\Exception
  549. * @throws \think\exception\PDOException
  550. */
  551. public function setPhrase($param)
  552. {
  553. if (!Db::name('crm_config')->where('name', 'activity_phrase')->value('value')) {
  554. return Db::name('crm_config')->insert(['name' => 'activity_phrase', 'value' => serialize($param), 'description' => '跟进记录常用语']);
  555. }
  556. Db::name('crm_config')->where('name', 'activity_phrase')->update(['value' => serialize($param)]);
  557. return true;
  558. }
  559. /**
  560. * 获取修改过的跟进记录信息
  561. *
  562. * @param $activityId
  563. * @param $userId
  564. * @return array|bool|\PDOStatement|string|\think\Model|null
  565. * @throws \think\db\exception\DataNotFoundException
  566. * @throws \think\db\exception\ModelNotFoundException
  567. * @throws \think\exception\DbException
  568. */
  569. public function getFollowData($activityId, $userId)
  570. {
  571. $field = [
  572. 'activity_id',
  573. 'type',
  574. 'category',
  575. 'activity_type',
  576. 'activity_type_id',
  577. 'content',
  578. 'contacts_ids',
  579. 'next_time',
  580. 'create_user_id',
  581. 'update_time',
  582. 'business_ids'
  583. ];
  584. $data = db('crm_activity')->where('activity_id', $activityId)->field($field)->find();
  585. $fileModel = new \app\admin\model\File();
  586. $realname = Db::name('admin_user')->where('id', $data['create_user_id'])->value('realname');
  587. $data['create_user_name'] = $realname;
  588. # 附件信息
  589. if ($data['type'] = 1) {
  590. $files = [];
  591. $images = [];
  592. $fileList = $fileModel->getDataList(['module' => 'crm_activity', 'module_id' => $activityId], 'all');
  593. if (!empty($fileList['list'])) {
  594. foreach ($fileList['list'] AS $k => $v) {
  595. if ($v['types'] == 'file') {
  596. $files[] = $v;
  597. } else {
  598. $images[] = $v;
  599. }
  600. }
  601. }
  602. $data['fileList'] = $files ? : [];
  603. $data['imgList'] = $images ? : [];
  604. }
  605. # 判断是不是本人添加的,如果不是将禁止删除修改
  606. $data['auth'] = false;
  607. if ($data['type'] == 1 && $data['create_user_id'] == $userId) {
  608. $data['auth'] = true;
  609. }
  610. # 查询联系人信息
  611. $data['contacts_name'] = '';
  612. if ($data['type'] == 1 && !empty($data['contacts_ids'])) {
  613. $data['contacts_name'] = Db::name('crm_contacts')->where('contacts_id', $data['contacts_ids'])->value('name');
  614. }
  615. $data['update_time'] = date('Y-m-d H:i:s', $data['update_time']);
  616. $data['next_time'] = !empty($data['next_time']) ? date('Y-m-d H:i:s', $data['next_time']) : null;
  617. # 关联商机
  618. $data['business_list'] = $data['activity_type'] == 2 ? $this->getBusinessInfo($data['business_ids']) : [];
  619. return $data;
  620. }
  621. /**
  622. * 获取活动类型名称
  623. *
  624. * @param $activityType
  625. * @param $activityTypeId
  626. * @return float|mixed|string|\think\db\Query
  627. */
  628. private function getActivityName($activityType, $activityTypeId)
  629. {
  630. $activityTypeName = '';
  631. # 线索
  632. if ($activityType == 1) {
  633. $activityTypeName = Db::name('crm_leads')->where('leads_id', $activityTypeId)->value('name');
  634. }
  635. # 客户
  636. if ($activityType == 2) {
  637. $activityTypeName = Db::name('crm_customer')->where('customer_id', $activityTypeId)->value('name');
  638. }
  639. # 联系人
  640. if ($activityType == 3) {
  641. $activityTypeName = Db::name('crm_contacts')->where('contacts_id', $activityTypeId)->value('name');
  642. }
  643. # 产品
  644. if ($activityType == 4) {
  645. $activityTypeName = Db::name('crm_product')->where('product_id', $activityTypeId)->value('name');
  646. }
  647. # 商机
  648. if ($activityType == 5) {
  649. $activityTypeName = Db::name('crm_business')->where('business_id', $activityTypeId)->value('name');
  650. }
  651. # 合同
  652. if ($activityType == 6) {
  653. $activityTypeName = Db::name('crm_contract')->where('contract_id', $activityTypeId)->value('name');
  654. }
  655. # 回款
  656. if ($activityType == 7) {
  657. $activityTypeName = Db::name('crm_receivables')->where('receivables_id', $activityTypeId)->value('number');
  658. }
  659. # 日志
  660. if ($activityType == 8) {
  661. $activityTypeName = Db::name('oa_log')->where('log_id', $activityTypeId)->value('title');
  662. }
  663. # 审批
  664. if ($activityType == 9) {
  665. $categoryId = Db::name('oa_examine')->where('examine_id', $activityTypeId)->value('category_id');
  666. $activityTypeName = Db::name('oa_examine_category')->where('category_id', $categoryId)->value('title');
  667. }
  668. # 日程
  669. if ($activityType == 10) {
  670. $activityTypeName = Db::name('oa_event')->where('event_id', $activityTypeId)->value('title');
  671. }
  672. # 任务
  673. if ($activityType == 11) {
  674. $activityTypeName = Db::name('task')->where('task_id', $activityTypeId)->value('name');
  675. }
  676. return $activityTypeName;
  677. }
  678. /**
  679. * 获取客户跟进记录关联的商机
  680. *
  681. * @param $businessIds
  682. * @return bool|\PDOStatement|string|\think\Collection
  683. * @throws \think\db\exception\DataNotFoundException
  684. * @throws \think\db\exception\ModelNotFoundException
  685. * @throws \think\exception\DbException
  686. */
  687. private function getBusinessInfo($businessIds)
  688. {
  689. return Db::name('crm_business')->field(['business_id', 'name'])->whereIn('business_id', $businessIds)->select();
  690. }
  691. /**
  692. * 设置跟进记录
  693. *
  694. * @param $type
  695. * @param $typeId
  696. * @param $content
  697. * @throws \think\Exception
  698. * @throws \think\exception\PDOException
  699. */
  700. private function setFollowRecord($type, $typeId, $content)
  701. {
  702. $model = null;
  703. $primaryKey = null;
  704. switch ($type) {
  705. case 1 : $model = db('crm_leads'); $primaryKey = 'leads_id'; break;
  706. case 2 : $model = db('crm_customer'); $primaryKey = 'customer_id'; break;
  707. case 3 : $model = db('crm_contacts'); $primaryKey = 'contacts_id'; break;
  708. case 5 : $model = db('crm_business'); $primaryKey = 'business_id'; break;
  709. case 6 : $model = db('crm_contract'); $primaryKey = 'contract_id'; break;
  710. }
  711. $model->where($primaryKey, $typeId)->update(['last_time' => time(), 'last_record' => $content]);
  712. }
  713. }