Contacts.php 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Description: 联系人
  4. // +----------------------------------------------------------------------
  5. // | Author: Michael_xu | gengxiaoxu@5kcrm.com
  6. // +----------------------------------------------------------------------
  7. namespace app\crm\model;
  8. use app\admin\traits\FieldVerificationTrait;
  9. use think\Db;
  10. use app\admin\model\Common;
  11. use think\Validate;
  12. class Contacts extends Common
  13. {
  14. use FieldVerificationTrait;
  15. /**
  16. * 为了数据库的整洁,同时又不影响Model和Controller的名称
  17. * 我们约定每个模块的数据表都加上相同的前缀,比如CRM模块用crm作为数据表前缀
  18. */
  19. protected $name = 'crm_contacts';
  20. protected $createTime = 'create_time';
  21. protected $updateTime = 'update_time';
  22. protected $autoWriteTimestamp = true;
  23. /**
  24. * [getDataList 联系人list]
  25. * @param [string] $map [查询条件]
  26. * @param [number] $page [当前页数]
  27. * @param [number] $limit [每页数量]
  28. * @return [array] [description]
  29. * @author Michael_xu
  30. */
  31. public function getDataList($request)
  32. {
  33. $userModel = new \app\admin\model\User();
  34. $structureModel = new \app\admin\model\Structure();
  35. $fieldModel = new \app\admin\model\Field();
  36. $customerModel = new \app\crm\model\Customer();
  37. $search = $request['search'];
  38. $user_id = $request['user_id'];
  39. $scene_id = (int)$request['scene_id'];
  40. $is_excel = $request['is_excel']; //导出
  41. $business_id = $request['business_id'];
  42. $order_field = $request['order_field'];
  43. $order_type = $request['order_type'];
  44. $pageType = $request['pageType'];
  45. $getCount = $request['getCount'];
  46. //需要过滤的参数
  47. $unsetRequest = ['scene_id', 'search', 'user_id', 'is_excel', 'action', 'order_field', 'order_type', 'is_remind', 'getCount', 'type', 'otherMap', 'business_id', 'check_status'];
  48. foreach ($unsetRequest as $v) {
  49. unset($request[$v]);
  50. }
  51. $request = $this->fmtRequest($request);
  52. $requestMap = $request['map'] ?: [];
  53. $sceneModel = new \app\admin\model\Scene();
  54. if ($scene_id) {
  55. //自定义场景
  56. $sceneMap = $sceneModel->getDataById($scene_id, $user_id, 'contacts') ?: [];
  57. } else {
  58. //默认场景
  59. $sceneMap = $sceneModel->getDefaultData('crm_contacts', $user_id) ?: [];
  60. }
  61. $searchMap = [];
  62. if ($search || $search == '0') {
  63. //普通筛选
  64. $searchMap = function ($query) use ($search) {
  65. $query->where('contacts.name', array('like', '%' . $search . '%'))
  66. ->whereOr('contacts.mobile', array('like', '%' . $search . '%'))
  67. ->whereOr('contacts.telephone', array('like', '%' . $search . '%'));
  68. };
  69. }
  70. $partMap = [];
  71. //优先级:普通筛选>高级筛选>场景
  72. if ($requestMap['team_id']) {
  73. //相关团队查询
  74. $map = $requestMap;
  75. $partMap= advancedQueryFormatForTeam($requestMap,'crm_contacts','contacts_id');
  76. unset($map['team_id']);
  77. } else {
  78. $map = $requestMap ? array_merge($sceneMap, $requestMap) : $sceneMap;
  79. }
  80. //高级筛选
  81. $map = advancedQuery($map, 'crm', 'contacts', 'index');
  82. //权限
  83. if (!$partMap) {
  84. $a = 'index';
  85. if ($is_excel) $a = 'excelExport';
  86. $authMap = [];
  87. $auth_user_ids = $userModel->getUserByPer('crm', 'contacts', $a);
  88. if (isset($map['contacts.owner_user_id']) && $map['contacts.owner_user_id'][0] != 'like') {
  89. if (!is_array($map['contacts.owner_user_id'][1])) {
  90. $map['contacts.owner_user_id'][1] = [$map['contacts.owner_user_id'][1]];
  91. }
  92. if (in_array($map['contacts.owner_user_id'][0], ['neq', 'notin'])) {
  93. $auth_user_ids = array_diff($auth_user_ids, $map['contacts.owner_user_id'][1]) ?: []; //取差集
  94. } else {
  95. $auth_user_ids = array_intersect($map['contacts.owner_user_id'][1], $auth_user_ids) ?: []; //取交集
  96. }
  97. unset($map['contacts.owner_user_id']);
  98. $auth_user_ids = array_merge(array_unique(array_filter($auth_user_ids))) ?: ['-1'];
  99. //负责人、相关团队
  100. $authMap['contacts.owner_user_id'] = ['in', $auth_user_ids];
  101. } else {
  102. $authMapData = [];
  103. $authMapData['auth_user_ids'] = $auth_user_ids;
  104. $authMapData['user_id'] = $user_id;
  105. $authMap = function ($query) use ($authMapData) {
  106. $query->where('contacts.owner_user_id', array('in', $authMapData['auth_user_ids']))
  107. ->whereOr('contacts.ro_user_id', array('like', '%,' . $authMapData['user_id'] . ',%'))
  108. ->whereOr('contacts.rw_user_id', array('like', '%,' . $authMapData['user_id'] . ',%'));
  109. };
  110. }
  111. }
  112. //联系人商机
  113. if ($business_id) {
  114. $contacts_id = Db::name('crm_contacts_business')->where(['business_id' => $business_id])->column('contacts_id');
  115. if ($contacts_id) {
  116. $map['contacts.contacts_id'] = array('in', $contacts_id);
  117. } else {
  118. $map['contacts.contacts_id'] = array('eq', -1);
  119. }
  120. }
  121. //列表展示字段
  122. $indexField = $fieldModel->getIndexField('crm_contacts', $user_id, 1) ?: array('name');
  123. $userField = $fieldModel->getFieldByFormType('crm_contacts', 'user'); //人员类型
  124. $structureField = $fieldModel->getFieldByFormType('crm_contacts', 'structure'); //部门类型
  125. $datetimeField = $fieldModel->getFieldByFormType('crm_contacts', 'datetime'); //日期时间类型
  126. $booleanField = $fieldModel->getFieldByFormType('crm_contacts', 'boolean_value'); //布尔值
  127. $dateIntervalField = $fieldModel->getFieldByFormType('crm_contacts', 'date_interval'); // 日期区间类型字段
  128. $positionField = $fieldModel->getFieldByFormType('crm_contacts', 'position'); // 地址类型字段
  129. $handwritingField = $fieldModel->getFieldByFormType('crm_contacts', 'handwriting_sign'); // 手写签名类型字段
  130. $locationField = $fieldModel->getFieldByFormType('crm_contacts', 'location'); // 定位类型字段
  131. # 处理人员和部门类型的排序报错问题(前端传来的是包含_name的别名字段)
  132. $temporaryField = str_replace('_name', '', $order_field);
  133. if (in_array($temporaryField, $userField) || in_array($temporaryField, $structureField)) {
  134. $order_field = $temporaryField;
  135. }
  136. //排序
  137. if ($order_type && $order_field) {
  138. $order = $fieldModel->getOrderByFormtype('crm_contacts', 'contacts', $order_field, $order_type);
  139. } else {
  140. $order = 'contacts.update_time desc';
  141. }
  142. $readAuthIds = $userModel->getUserByPer('crm', 'contacts', 'read');
  143. $updateAuthIds = $userModel->getUserByPer('crm', 'contacts', 'update');
  144. $deleteAuthIds = $userModel->getUserByPer('crm', 'contacts', 'delete');
  145. $customerWhere = [];
  146. if ($pageType == !'all') {
  147. //非客户池条件
  148. $customerWhere = $customerModel->getWhereByCustomer();
  149. }
  150. $dataCount = db('crm_contacts')
  151. ->alias('contacts')
  152. ->join('__CRM_CUSTOMER__ customer', 'contacts.customer_id = customer.customer_id', 'LEFT')
  153. ->where($map)
  154. ->where($searchMap)
  155. ->where($authMap)
  156. ->where($partMap)
  157. ->where($customerWhere)
  158. ->count('contacts_id');
  159. if ($getCount == 1) {
  160. $data['dataCount'] = $dataCount ?: 0;
  161. return $data;
  162. }
  163. $list = db('crm_contacts')
  164. ->alias('contacts')
  165. ->join('__CRM_CUSTOMER__ customer', 'contacts.customer_id = customer.customer_id', 'LEFT')
  166. ->where($map)
  167. ->where($searchMap)
  168. ->where($partMap)
  169. ->where($authMap)
  170. ->where($customerWhere)
  171. ->limit($request['offset'], $request['length'])
  172. ->field('contacts.*,customer.name as customer_name')
  173. ->orderRaw($order)
  174. ->select();
  175. # 扩展数据
  176. $extraData = [];
  177. $contacts_id_list = !empty($list) ? array_column($list, 'contacts_id') : [];
  178. $extraList = db('crm_contacts_data')->whereIn('contacts_id', $contacts_id_list)->select();
  179. foreach ($extraList as $key => $value) {
  180. $extraData[$value['contacts_id']][$value['field']] = $value['content'];
  181. }
  182. foreach ($list as $k => $v) {
  183. $list[$k]['create_user_id_info'] = isset($v['create_user_id']) ? $userModel->getUserById($v['create_user_id']) : [];
  184. $list[$k]['owner_user_id_info'] = isset($v['owner_user_id']) ? $userModel->getUserById($v['owner_user_id']) : [];
  185. $list[$k]['customer_id_info']['customer_id'] = $v['customer_id'] ?: '';
  186. $list[$k]['customer_id_info']['name'] = $v['customer_name'] ?: '';
  187. foreach ($userField as $key => $val) {
  188. $usernameField = !empty($v[$val]) ? db('admin_user')->whereIn('id', stringToArray($v[$val]))->column('realname') : [];
  189. $list[$k][$val] = implode($usernameField, ',');
  190. }
  191. foreach ($structureField as $key => $val) {
  192. $structureNameField = !empty($v[$val]) ? db('admin_structure')->whereIn('id', stringToArray($v[$val]))->column('name') : [];
  193. $list[$k][$val] = implode($structureNameField, ',');
  194. }
  195. foreach ($datetimeField as $key => $val) {
  196. $list[$k][$val] = !empty($v[$val]) ? date('Y-m-d H:i:s', $v[$val]) : null;
  197. }
  198. foreach ($booleanField as $key => $val) {
  199. $list[$k][$val] = !empty($v[$val]) ? (string)$v[$val] : '0';
  200. }
  201. // 处理日期区间类型字段的格式
  202. foreach ($dateIntervalField as $key => $val) {
  203. $list[$k][$val] = !empty($extraData[$v['contacts_id']][$val]) ? json_decode($extraData[$v['contacts_id']][$val], true) : null;
  204. }
  205. // 处理地址类型字段的格式
  206. foreach ($positionField as $key => $val) {
  207. $list[$k][$val] = !empty($extraData[$v['contacts_id']][$val]) ? json_decode($extraData[$v['contacts_id']][$val], true) : null;
  208. }
  209. // 手写签名类型字段
  210. foreach ($handwritingField as $key => $val) {
  211. $handwritingData = !empty($v[$val]) ? db('admin_file')->where('file_id', $v[$val])->value('file_path') : null;
  212. $list[$k][$val] = ['url' => !empty($handwritingData) ? getFullPath($handwritingData) : null];
  213. }
  214. // 定位类型字段
  215. foreach ($locationField AS $key => $val) {
  216. $list[$k][$val] = !empty($extraData[$v['contacts_id']][$val]) ? json_decode($extraData[$v['contacts_id']][$val], true) : null;
  217. }
  218. //权限
  219. $permission = [];
  220. $is_read = 0;
  221. $is_update = 0;
  222. $is_delete = 0;
  223. if (in_array($v['owner_user_id'], $readAuthIds)) $is_read = 1;
  224. if (in_array($v['owner_user_id'], $updateAuthIds)) $is_update = 1;
  225. if (in_array($v['owner_user_id'], $deleteAuthIds)) $is_delete = 1;
  226. $permission['is_read'] = $is_read;
  227. $permission['is_update'] = $is_update;
  228. $permission['is_delete'] = $is_delete;
  229. $list[$k]['permission'] = $permission;
  230. # 关注
  231. $starWhere = ['user_id' => $user_id, 'target_id' => $v['contacts_id'], 'type' => 'crm_contacts'];
  232. $star = Db::name('crm_star')->where($starWhere)->value('star_id');
  233. $list[$k]['star'] = !empty($star) ? 1 : 0;
  234. # 日期
  235. $list[$k]['create_time'] = !empty($v['create_time']) ? date('Y-m-d H:i:s', $v['create_time']) : null;
  236. $list[$k]['update_time'] = !empty($v['update_time']) ? date('Y-m-d H:i:s', $v['update_time']) : null;
  237. $list[$k]['last_time'] = !empty($v['last_time']) ? date('Y-m-d H:i:s', $v['last_time']) : null;
  238. # 创建人
  239. $list[$k]['create_user_name'] = !empty($list[$k]['create_user_id_info']['realname']) ? $list[$k]['create_user_id_info']['realname'] : '';
  240. # 负责人
  241. $list[$k]['owner_user_name'] = !empty($list[$k]['owner_user_id_info']['realname']) ? $list[$k]['owner_user_id_info']['realname'] : '';
  242. }
  243. $data = [];
  244. $data['list'] = $list;
  245. $data['dataCount'] = $dataCount ?: 0;
  246. return $data;
  247. }
  248. /**
  249. * 创建联系人主表信息
  250. * @param
  251. * @return
  252. * @author Michael_xu
  253. */
  254. public function createData($param)
  255. {
  256. unset($param['excel']);
  257. // 联系人扩展表数据
  258. $contactsData = [];
  259. $businessId = $param['business_id'];
  260. unset($param['business_id']);
  261. $fieldModel = new \app\admin\model\Field();
  262. // 数据验证
  263. $validateResult = $this->fieldDataValidate($param, $this->name, $param['create_user_id']);
  264. if (!empty($validateResult)) {
  265. $this->error = $validateResult;
  266. return false;
  267. }
  268. # 处理客户首要联系人
  269. $primaryStatus = Db::name('crm_contacts')->where('customer_id', $param['customer_id'])->value('contacts_id');
  270. if (!empty($param['primary']) && $param['primary'] == 1 && !empty($primaryStatus)) {
  271. # 设置首要联系人,去除其他首要联系人状态
  272. Db::name('crm_contacts')->where('customer_id', $param['customer_id'])->update(['primary' => 0]);
  273. }
  274. if (!empty($param['customer_id']) && empty($primaryStatus)) {
  275. # 为客户添加第一个联系人默认设置成首要联系人
  276. $param['primary'] = 1;
  277. }
  278. // 处理部门、员工、附件、多选类型字段
  279. $arrFieldAtt = $fieldModel->getArrayField('crm_contacts');
  280. foreach ($arrFieldAtt as $k => $v) {
  281. $param[$v] = arrayToString($param[$v]);
  282. }
  283. // 处理日期(date)类型
  284. $dateField = $fieldModel->getFieldByFormType('crm_contacts', 'date');
  285. if (!empty($dateField)) {
  286. foreach ($param as $key => $value) {
  287. if (in_array($key, $dateField) && empty($value)) $param[$key] = null;
  288. }
  289. }
  290. // 处理手写签名类型
  291. $handwritingField = $fieldModel->getFieldByFormType('crm_contacts', 'handwriting_sign');
  292. if (!empty($handwritingField)) {
  293. foreach ($param as $key => $value) {
  294. if (in_array($key, $handwritingField)) {
  295. $param[$key] = !empty($value['file_id']) ? $value['file_id'] : '';
  296. }
  297. }
  298. }
  299. // 处理地址、定位、日期区间、明细表格类型字段
  300. $positionField = $fieldModel->getFieldByFormType($this->name, 'position');
  301. $locationField = $fieldModel->getFieldByFormType($this->name, 'location');
  302. $dateIntervalField = $fieldModel->getFieldByFormType($this->name, 'date_interval');
  303. $detailTableField = $fieldModel->getFieldByFormType($this->name, 'detail_table');
  304. foreach ($param as $key => $value) {
  305. // 处理地址类型字段数据
  306. if (in_array($key, $positionField)) {
  307. if (!empty($value)) {
  308. $contactsData[] = [
  309. 'field' => $key,
  310. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  311. 'create_time' => time()
  312. ];
  313. $positionNames = array_column($value, 'name');
  314. $param[$key] = implode(',', $positionNames);
  315. } else {
  316. $param[$key] = '';
  317. }
  318. }
  319. // 处理定位类型字段数据
  320. if (in_array($key, $locationField)) {
  321. if (!empty($value)) {
  322. $contactsData[] = [
  323. 'field' => $key,
  324. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  325. 'create_time' => time()
  326. ];
  327. $param[$key] = $value['address'];
  328. } else {
  329. $param[$key] = '';
  330. }
  331. }
  332. // 处理日期区间类型字段数据
  333. if (in_array($key, $dateIntervalField)) {
  334. if (!empty($value)) {
  335. $contactsData[] = [
  336. 'field' => $key,
  337. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  338. 'create_time' => time()
  339. ];
  340. $param[$key] = implode('_', $value);
  341. } else {
  342. $param[$key] = '';
  343. }
  344. }
  345. // 处理明细表格类型字段数据
  346. if (in_array($key, $detailTableField)) {
  347. if (!empty($value)) {
  348. $contactsData[] = [
  349. 'field' => $key,
  350. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  351. 'create_time' => time()
  352. ];
  353. $param[$key] = $key;
  354. } else {
  355. $param[$key] = '';
  356. }
  357. }
  358. }
  359. if ($this->data($param)->allowField(true)->isUpdate(false)->save()) {
  360. updateActionLog($param['create_user_id'], 'crm_contacts', $this->contacts_id, '', '', '创建了联系人');
  361. RecordActionLog($param['create_user_id'], 'crm_contacts', 'save', $param['name'], '', '', '新增了联系人' . $param['name']);
  362. $data = [];
  363. $data['contacts_id'] = $this->contacts_id;
  364. # 添加活动记录
  365. Db::name('crm_activity')->insert([
  366. 'type' => 2,
  367. 'activity_type' => 3,
  368. 'activity_type_id' => $data['contacts_id'],
  369. 'content' => $param['name'],
  370. 'create_user_id' => $param['create_user_id'],
  371. 'update_time' => time(),
  372. 'create_time' => time(),
  373. 'customer_ids' => ',' . $param['customer_id'] . ','
  374. ]);
  375. # 处理商机首要联系人
  376. if (!empty($businessId)) {
  377. Db::name('crm_business')->where('business_id', $businessId)->update(['contacts_id' => $data['contacts_id']]);
  378. }
  379. // 添加联系人扩展数据
  380. array_walk($contactsData, function (&$val) use ($data) {
  381. $val['contacts_id'] = $data['contacts_id'];
  382. });
  383. db('crm_contacts_data')->insertAll($contactsData);
  384. return $data;
  385. } else {
  386. $this->error = '添加失败';
  387. return false;
  388. }
  389. }
  390. //根据IDs获取数组
  391. public function getDataByStr($idstr)
  392. {
  393. $idArr = stringToArray($idstr);
  394. if (!$idArr) {
  395. return [];
  396. }
  397. $list = Db::name('CrmContacts')->where(['contacts_id' => ['in', $idArr]])->select();
  398. return $list;
  399. }
  400. /**
  401. * 编辑联系人主表信息
  402. *
  403. * @param $param
  404. * @param string $contacts_id
  405. * @return array|bool
  406. * @throws \think\Exception
  407. * @throws \think\db\exception\DataNotFoundException
  408. * @throws \think\db\exception\ModelNotFoundException
  409. * @throws \think\exception\DbException
  410. * @throws \think\exception\PDOException
  411. */
  412. public function updateDataById($param, $contacts_id = '')
  413. {
  414. // 联系人扩展表数据
  415. $contactsData = [];
  416. $userModel = new \app\admin\model\User();
  417. $dataInfo = $this->getDataById($contacts_id);
  418. if (!$dataInfo) {
  419. $this->error = '数据不存在或已删除';
  420. return false;
  421. }
  422. //判断权限
  423. $auth_user_ids = $userModel->getUserByPer('crm', 'contacts', 'update');
  424. if (!in_array($dataInfo['owner_user_id'], $auth_user_ids)) {
  425. $this->error = '无权操作';
  426. return false;
  427. }
  428. $param['contacts_id'] = $contacts_id;
  429. //过滤不能修改的字段
  430. $unUpdateField = ['create_user_id', 'is_deleted', 'delete_time'];
  431. foreach ($unUpdateField as $v) {
  432. unset($param[$v]);
  433. }
  434. $fieldModel = new \app\admin\model\Field();
  435. // 数据验证
  436. $validateResult = $this->fieldDataValidate($param, $this->name, $param['user_id'], $param['contacts_id']);
  437. if (!empty($validateResult)) {
  438. $this->error = $validateResult;
  439. return false;
  440. }
  441. // 处理部门、员工、附件、多选类型字段
  442. $arrFieldAtt = $fieldModel->getArrayField('crm_contacts');
  443. foreach ($arrFieldAtt as $k => $v) {
  444. if (isset($param[$v])) $param[$v] = arrayToString($param[$v]);
  445. }
  446. // 处理日期(date)类型
  447. $dateField = $fieldModel->getFieldByFormType('crm_contacts', 'date');
  448. if (!empty($dateField)) {
  449. foreach ($param as $key => $value) {
  450. if (in_array($key, $dateField) && empty($value)) $param[$key] = null;
  451. }
  452. }
  453. // 处理手写签名类型
  454. $handwritingField = $fieldModel->getFieldByFormType('crm_contacts', 'handwriting_sign');
  455. if (!empty($handwritingField)) {
  456. foreach ($param as $key => $value) {
  457. if (in_array($key, $handwritingField)) {
  458. $param[$key] = !empty($value['file_id']) ? $value['file_id'] : '';
  459. }
  460. }
  461. }
  462. // 处理地址、定位、日期区间、明细表格类型字段
  463. $positionField = $fieldModel->getFieldByFormType($this->name, 'position');
  464. $locationField = $fieldModel->getFieldByFormType($this->name, 'location');
  465. $dateIntervalField = $fieldModel->getFieldByFormType($this->name, 'date_interval');
  466. $detailTableField = $fieldModel->getFieldByFormType($this->name, 'detail_table');
  467. foreach ($param as $key => $value) {
  468. // 处理地址类型字段数据
  469. if (in_array($key, $positionField)) {
  470. if (!empty($value)) {
  471. $contactsData[] = [
  472. 'field' => $key,
  473. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  474. 'create_time' => time()
  475. ];
  476. $positionNames = array_column($value, 'name');
  477. $param[$key] = implode(',', $positionNames);
  478. } else {
  479. $param[$key] = '';
  480. }
  481. }
  482. // 处理定位类型字段数据
  483. if (in_array($key, $locationField)) {
  484. if (!empty($value)) {
  485. $contactsData[] = [
  486. 'field' => $key,
  487. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  488. 'create_time' => time()
  489. ];
  490. $param[$key] = $value['address'];
  491. } else {
  492. $param[$key] = '';
  493. }
  494. }
  495. // 处理日期区间类型字段数据
  496. if (in_array($key, $dateIntervalField)) {
  497. if (!empty($value)) {
  498. $contactsData[] = [
  499. 'field' => $key,
  500. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  501. 'create_time' => time()
  502. ];
  503. $param[$key] = implode('_', $value);
  504. } else {
  505. $param[$key] = '';
  506. }
  507. }
  508. // 处理明细表格类型字段数据
  509. if (in_array($key, $detailTableField)) {
  510. if (!empty($value)) {
  511. $contactsData[] = [
  512. 'field' => $key,
  513. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  514. 'create_time' => time()
  515. ];
  516. $param[$key] = $key;
  517. } else {
  518. $param[$key] = '';
  519. }
  520. }
  521. }
  522. # 处理首要联系人
  523. $primaryStatus = Db::name('crm_contacts')->where('customer_id', $param['customer_id'])->value('contacts_id');
  524. if (!empty($param['primary']) && $param['primary'] == 1 && !empty($primaryStatus)) {
  525. # 设置首要联系人,去除其他首要联系人状态
  526. Db::name('crm_contacts')->where('customer_id', $param['customer_id'])->update(['primary' => 0]);
  527. }
  528. if (!empty($param['customer_id']) && empty($primaryStatus)) {
  529. # 为客户添加第一个联系人默认设置成首要联系人
  530. $param['primary'] = 1;
  531. }
  532. if ($this->update($param, ['contacts_id' => $contacts_id], true)) {
  533. $data['contacts_id'] = $contacts_id;
  534. //修改记录
  535. updateActionLog($param['user_id'], 'crm_contacts', $contacts_id, $dataInfo, $param);
  536. RecordActionLog($param['user_id'], 'crm_contacts', 'update', $dataInfo['name'], $dataInfo, $param);
  537. // 添加联系人扩展数据
  538. db('crm_contacts_data')->where('contacts_id', $contacts_id)->delete();
  539. array_walk($contactsData, function (&$val) use ($contacts_id) {
  540. $val['contacts_id'] = $contacts_id;
  541. });
  542. db('crm_contacts_data')->insertAll($contactsData);
  543. return $data;
  544. } else {
  545. $this->error = '编辑失败';
  546. return false;
  547. }
  548. }
  549. /**
  550. * 联系人数据
  551. *
  552. * @param string $id
  553. * @param int $userId
  554. * @return Common|array|bool|\PDOStatement|string|\think\Model|null
  555. * @throws \think\db\exception\DataNotFoundException
  556. * @throws \think\db\exception\ModelNotFoundException
  557. * @throws \think\exception\DbException
  558. */
  559. public function getDataById($id = '', $userId = 0)
  560. {
  561. $map['contacts_id'] = $id;
  562. $dataInfo = db('crm_contacts')->where($map)->find();
  563. if (!$dataInfo) {
  564. $this->error = '暂无此数据';
  565. return false;
  566. }
  567. $userModel = new \app\admin\model\User();
  568. $dataInfo['create_user_id_info'] = isset($dataInfo['create_user_id']) ? $userModel->getUserById($dataInfo['create_user_id']) : [];
  569. $dataInfo['owner_user_id_info'] = isset($dataInfo['owner_user_id']) ? $userModel->getUserById($dataInfo['owner_user_id']) : [];
  570. $dataInfo['customer_id_info'] = db('crm_customer')->where(['customer_id' => $dataInfo['customer_id']])->field('customer_id,name,mobile,telephone,deal_status')->find();
  571. $dataInfo['customer_name'] = !empty($dataInfo['customer_id_info']['name']) ? $dataInfo['customer_id_info']['name'] : '';
  572. $dataInfo['create_user_name'] = !empty($dataInfo['create_user_id_info']['realname']) ? $dataInfo['create_user_id_info']['realname'] : '';
  573. $dataInfo['owner_user_name'] = !empty($dataInfo['owner_user_id_info']['realname']) ? $dataInfo['owner_user_id_info']['realname'] : '';
  574. # 关注
  575. $starId = empty($userId) ? 0 : Db::name('crm_star')->where(['user_id' => $userId, 'target_id' => $id, 'type' => 'crm_contacts'])->value('star_id');
  576. $dataInfo['star'] = !empty($starId) ? 1 : 0;
  577. # 处理决策人显示问题
  578. $dataInfo['decision'] = !empty($dataInfo['decision']) && $dataInfo['decision'] == '是' ? '是' : '否';
  579. # 处理时间格式
  580. $fieldModel = new \app\admin\model\Field();
  581. $datetimeField = $fieldModel->getFieldByFormType('crm_contacts', 'datetime'); //日期时间类型
  582. foreach ($datetimeField as $key => $val) {
  583. $dataInfo[$val] = !empty($dataInfo[$val]) ? date('Y-m-d H:i:s', $dataInfo[$val]) : null;
  584. }
  585. $dataInfo['create_time'] = !empty($dataInfo['create_time']) ? date('Y-m-d H:i:s', $dataInfo['create_time']) : null;
  586. $dataInfo['update_time'] = !empty($dataInfo['update_time']) ? date('Y-m-d H:i:s', $dataInfo['update_time']) : null;
  587. $dataInfo['last_time'] = !empty($dataInfo['last_time']) ? date('Y-m-d H:i:s', $dataInfo['last_time']) : null;
  588. // 字段授权
  589. if (!empty($userId)) {
  590. $grantData = getFieldGrantData($userId);
  591. $userLevel = isSuperAdministrators($userId);
  592. foreach ($dataInfo as $key => $value) {
  593. if (!$userLevel && !empty($grantData['crm_contacts'])) {
  594. $status = getFieldGrantStatus($key, $grantData['crm_contacts']);
  595. # 查看权限
  596. if ($status['read'] == 0) unset($dataInfo[$key]);
  597. }
  598. }
  599. }
  600. return $dataInfo;
  601. }
  602. /**
  603. * [联系人转移]
  604. * @param ids 联系人ID数组
  605. * @param owner_user_id 变更负责人
  606. * @param is_remove 1移出,2转为团队成员
  607. * @return
  608. * @author Michael_xu
  609. */
  610. public function transferDataById($ids, $owner_user_id, $type = 1, $is_remove)
  611. {
  612. $settingModel = new \app\crm\model\Setting();
  613. foreach ($ids as $id) {
  614. $data = [];
  615. $data['owner_user_id'] = $owner_user_id;
  616. $data['update_time'] = time();
  617. db('crm_contacts')->where(['contacts_id' => $id])->update($data);
  618. }
  619. return true;
  620. }
  621. /**
  622. * 设置首要联系人
  623. *
  624. * @param $customerId
  625. * @param $contactsId
  626. * @return bool
  627. * @throws \think\Exception
  628. * @throws \think\exception\PDOException
  629. */
  630. public function setPrimary($customerId, $contactsId)
  631. {
  632. Db::name('crm_contacts')->where('customer_id', $customerId)->update(['primary' => 0]);
  633. Db::name('crm_contacts')->where(['customer_id' => $customerId, 'contacts_id' => $contactsId])->update(['primary' => 1]);
  634. return true;
  635. }
  636. /**
  637. * 获取跟进记录联系人
  638. *
  639. * @param $customerId
  640. * @return bool|\PDOStatement|string|\think\Collection
  641. * @throws \think\db\exception\DataNotFoundException
  642. * @throws \think\db\exception\ModelNotFoundException
  643. * @throws \think\exception\DbException
  644. */
  645. public function getContactsList($customerId)
  646. {
  647. return Db::name('crm_contacts')->field(['contacts_id', 'name', 'mobile', 'telephone', 'detail_address'])->where('customer_id', $customerId)->order('primary', 'desc')->select();
  648. }
  649. /**
  650. * 获取系统信息
  651. *
  652. * @param $id
  653. * @return array
  654. * @throws \think\db\exception\DataNotFoundException
  655. * @throws \think\db\exception\ModelNotFoundException
  656. * @throws \think\exception\DbException
  657. */
  658. public function getSystemInfo($id)
  659. {
  660. # 联系人
  661. $contacts = Db::name('crm_contacts')->field(['create_user_id', 'create_time', 'update_time', 'last_time'])->where('contacts_id', $id)->find();
  662. # 创建人
  663. $realname = Db::name('admin_user')->where('id', $contacts['create_user_id'])->value('realname');
  664. return [
  665. 'create_user_id' => $realname,
  666. 'create_time' => date('Y-m-d H:i:s', $contacts['create_time']),
  667. 'update_time' => date('Y-m-d H:i:s', $contacts['update_time']),
  668. 'last_time' => !empty($contacts['last_time']) ? date('Y-m-d H:i:s', $contacts['last_time']) : ''
  669. ];
  670. }
  671. }