Scene.php 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Description: 场景
  4. // +----------------------------------------------------------------------
  5. // | Author: Michael_xu | gengxiaoxu@5kcrm.com
  6. // +----------------------------------------------------------------------
  7. namespace app\admin\model;
  8. use think\Db;
  9. use app\admin\model\Common;
  10. class Scene extends Common
  11. {
  12. /**
  13. * 为了数据库的整洁,同时又不影响Model和Controller的名称
  14. * 我们约定每个模块的数据表都加上相同的前缀,比如CRM模块用crm作为数据表前缀
  15. */
  16. protected $name = 'admin_scene';
  17. protected $createTime = 'create_time';
  18. protected $updateTime = false;
  19. protected $autoWriteTimestamp = true;
  20. private $types_arr = ['crm_leads','crm_customer','crm_customer_pool','crm_contacts','crm_product','crm_business','crm_contract','crm_receivables','crm_visit','crm_invoice']; //支持场景的分类
  21. protected $type = [
  22. 'data' => 'array',
  23. ];
  24. /**
  25. * 创建场景
  26. * @param
  27. * @return
  28. */
  29. public function createData($param, $types = '')
  30. {
  31. if (empty($types)) {
  32. $this->error = '参数错误';
  33. return false;
  34. }
  35. if (empty($param['name'])) {
  36. $this->error = '场景名称必填';
  37. return false;
  38. }
  39. $user_id = $param['user_id'];
  40. if ($this->where(['types'=>$types,'user_id'=>$user_id,'name'=>$param['name']])->find()) {
  41. $this->error = '场景名称已存在';
  42. return false;
  43. }
  44. # 转自定义场景结构
  45. $sceneData = [];
  46. foreach ($param['data'] AS $key => $value) {
  47. foreach ($value AS $k => $v) {
  48. $sceneData[$k] = [
  49. 'condition' => trim($v['condition']),
  50. 'value' => $v['value'],
  51. 'form_type' => $v['form_type'],
  52. 'name' => $v['name'],
  53. 'type' => $v['type']
  54. ];
  55. if (!empty($v['start'])) $sceneData[$k]['start'] = $v['start'];
  56. if (!empty($v['end'])) $sceneData[$k]['end'] = $v['end'];
  57. }
  58. }
  59. if (!empty($sceneData)) $param['data'] = $sceneData;
  60. $max_order_id = $this->getMaxOrderid($types, $user_id);
  61. $param['order_id'] = $max_order_id ? $max_order_id+1 : 0;
  62. $param['update_time'] = time();
  63. $param['type'] = 0;
  64. $param['bydata'] = '';
  65. $res = $this->allowField(true)->save($param);
  66. if ($res) {
  67. //设置默认
  68. if ($param['is_default']) {
  69. $defaultData = [];
  70. $defaultData['types'] = $types;
  71. $defaultData['user_id'] = $user_id;
  72. $this->defaultDataById($defaultData, $this->scene_id);
  73. }
  74. return true;
  75. } else {
  76. $this->error = '添加失败';
  77. return false;
  78. }
  79. }
  80. /**
  81. * [getDataList 场景list]
  82. * @param types 分类
  83. * @author Michael_xu
  84. * @return [array]
  85. */
  86. public function getDataList($types, $user_id)
  87. {
  88. $fieldModel = new \app\admin\model\Field();
  89. $userModel = new \app\admin\model\User();
  90. if (!in_array($types, $this->types_arr)) {
  91. $this->error = '参数错误';
  92. return false;
  93. }
  94. $map['user_id'] = $user_id;
  95. $map['is_hide'] = 0;
  96. $map['types'] = $types;
  97. $list = db('admin_scene')
  98. ->where($map)
  99. ->whereOr(function ($query) use ($types) {
  100. $query->where(['types' => $types,'type' => 1]);
  101. })->order('order_id asc,scene_id asc')
  102. ->select();
  103. $defaultSceneId = db('admin_scene_default')->where(['types' => $types,'user_id' => $user_id])->value('scene_id');
  104. $fieldList = $fieldModel->getField(['types' => $types]);
  105. $newFieldList = [];
  106. foreach ($fieldList as $k=>$v) {
  107. $field = $v['field'];
  108. if ($v['field'] == 'customer_id') $field = 'customer_name';
  109. $newFieldList[$field] = $v;
  110. }
  111. foreach ($list as $k=>$v) {
  112. if ($v['scene_id'] == $defaultSceneId) {
  113. $list[$k]['is_default'] = 1;
  114. }
  115. $data = $v['data'] ? json_decode($v['data'],true) : [];
  116. if ($data) {
  117. foreach ($data as $key=>$val) {
  118. $setting = $newFieldList[$key]['setting'];
  119. $data[$key]['setting'] = $setting;
  120. if ($val['form_type'] == 'user' && !empty($val['value'][0])) {
  121. $userInfo = $userModel->getUserById($val['value'][0]);
  122. $data[$key]['setting']['realname'] = $userInfo['realname'];
  123. $data[$key]['setting']['id'] = $userInfo['id'];
  124. }
  125. }
  126. }
  127. $list[$k]['data'] = $data ? : [];
  128. }
  129. $map['is_hide'] = 1;
  130. $hideList = $this->where($map)->order('order_id asc')->select();
  131. $data = [];
  132. $data['list'] = $list;
  133. $data['hideList'] = $hideList;
  134. return $data;
  135. }
  136. /**
  137. * 根据主键获取详情
  138. * @param array $param [description]
  139. * @author Michael_xu
  140. */
  141. public function getDataById($id = '', $user_id = '', $types = '')
  142. {
  143. $where = [];
  144. $where['scene_id'] = $id;
  145. // $where['user_id'] = [['=',$user_id],['=',0],'or'];
  146. $data = db('admin_scene')->where($where)->find();
  147. if (!$types) {
  148. $types = $data['types'] ? : '';
  149. }
  150. //处理data
  151. if ($data['bydata'] && $types) {
  152. $data = $this->getByData($types, $data['bydata'], $user_id);
  153. } else {
  154. $data = json_decode($data['data'],true);
  155. if (is_array($data)) {
  156. foreach ($data as $k=>$v) {
  157. if ($v['form_type'] == 'business_type') {
  158. $data[$k]['value'] = $v['type_id'];
  159. }
  160. }
  161. }
  162. }
  163. return $data ? : [];
  164. }
  165. /**
  166. * 根据主键修改
  167. * @param array $param [description]
  168. * @author Michael_xu
  169. */
  170. public function updateDataById($param, $id)
  171. {
  172. $checkData = $this->get($id);
  173. $sceneInfo = $checkData->data;
  174. $user_id = $param['user_id'];
  175. if (!$sceneInfo) {
  176. $this->error = '暂无数据';
  177. return false;
  178. }
  179. //权限(只能编辑自己的)
  180. if ($sceneInfo['user_id'] !== $user_id) {
  181. $this->error = '参数错误';
  182. return false;
  183. }
  184. if (empty($param['name'])) {
  185. $this->error = '场景名称必填';
  186. return false;
  187. }
  188. if ($this->where(['scene_id' => ['neq', $id], 'types' => $param['types'], 'user_id' => $user_id,'name' => $param['name']])->find()) {
  189. $this->error = '场景名称已存在';
  190. return false;
  191. }
  192. # 转自定义场景结构
  193. $sceneData = [];
  194. foreach ($param['data'] AS $key => $value) {
  195. foreach ($value AS $k => $v) {
  196. $sceneData[$k] = [
  197. 'condition' => trim($v['condition']),
  198. 'value' => $v['value'],
  199. 'form_type' => $v['form_type'],
  200. 'name' => $v['name'],
  201. 'type' => $v['type']
  202. ];
  203. if (!empty($v['start'])) $sceneData[$k]['start'] = $v['start'];
  204. if (!empty($v['end'])) $sceneData[$k]['end'] = $v['end'];
  205. }
  206. }
  207. if (!empty($sceneData)) $param['data'] = $sceneData;
  208. $param['update_time'] = time();
  209. // $scene_data = $this->dataChangeString($param);
  210. //处理data数据
  211. $res = $this->allowField(true)->save($param, ['scene_id' => $id]);
  212. if ($param['is_default'] == 1) {
  213. $this->defaultDataById($param,$param['id']);
  214. } else {
  215. db('admin_scene_default')->where(['user_id' => $user_id, 'types' => $param['types'], 'scene_id' => $id])->delete();
  216. }
  217. if ($res) {
  218. return true;
  219. } else {
  220. $this->error = '修改失败';
  221. return false;
  222. }
  223. }
  224. /**
  225. * 场景设置为默认
  226. * @param types 类型
  227. * @param user_id 人员ID
  228. * @param id 场景ID
  229. * @author Michael_xu
  230. */
  231. public function defaultDataById($param, $id)
  232. {
  233. if (!$param['types'] || !$id) {
  234. $this->error = '参数错误';
  235. return false;
  236. }
  237. $resInfo = db('admin_scene_default')->where(['types' => $param['types'],'user_id' => $param['user_id']])->find();
  238. if ($resInfo) {
  239. $res = db('admin_scene_default')->where(['types' => $param['types'],'user_id' => $param['user_id']])->update(['scene_id' => $id]);
  240. } else {
  241. $data = [];
  242. $data['types'] = $param['types'];
  243. $data['user_id'] = $param['user_id'];
  244. $data['scene_id'] = $id;
  245. $res = db('admin_scene_default')->insert($data);
  246. }
  247. if (!$res) {
  248. $this->error = '设置失败或数据无变化';
  249. return false;
  250. }
  251. return true;
  252. }
  253. /**
  254. * 场景数据转换(字符串形式存储)
  255. * @param
  256. * @author Michael_xu
  257. * @return
  258. */
  259. public function dataChangeString($param = [])
  260. {
  261. $scene_data = '[';
  262. $field_arr = [];
  263. $i = 0;
  264. foreach ($param['data'] as $k=>$v) {
  265. if ($v != '' && !in_array($v['field'], $field_arr)) {
  266. $i++;
  267. if ($i == 1) {
  268. $scene_data .= $v['field']."=>[";
  269. } else {
  270. $scene_data .= ",".$v['field']."=>[";
  271. }
  272. $scene_data .= "field=>".$v['field'].",";
  273. //处理条件和值
  274. foreach ($param as $k1=>$v1) {
  275. switch ($k1) {
  276. case 'condition' : $scene_data .= "condition=>".$v1.","; break;
  277. case 'value' : $scene_data .= "value=>".$v1.","; break;
  278. case 'state' :
  279. case 'city' :
  280. case 'area' :
  281. //处理地址类型数据
  282. $scene_data .= $k1."=>".$v1.","; break;
  283. case 'start' : $scene_data .= "start=>".$v1.","; break;
  284. case 'end' : $scene_data .= "end=>".$v1.","; break;
  285. case 'start_date' : $scene_data .= "start_date=>".$v1.","; break;
  286. case 'end_date' : $scene_data .= "end_date=>".$v1.","; break;
  287. }
  288. }
  289. $form_type = '';
  290. //处理字段类型
  291. if ($v['field'] == 'create_time' || $v['field'] == 'update_time') {
  292. $form_type = 'datetime';
  293. } else {
  294. $form_type = db('admin_fields')->where(['types'=>$param['types'],'field'=>$v['field'],'is_main'=>1])->column('form_type');
  295. }
  296. $scene_data .= "form_type=>".$form_type;
  297. $field_arr[] = $v['field'];
  298. }
  299. $scene_data .= ']';
  300. }
  301. $scene_data .= ']';
  302. return $scene_data;
  303. }
  304. /**
  305. * 场景排序最大值
  306. * @param
  307. * @author Michael_xu
  308. * @return
  309. */
  310. public function getMaxOrderid($types, $user_id)
  311. {
  312. $maxOrderid = $this->where(['types' => $types, 'user_id' => $user_id])->max('order_id');
  313. return $maxOrderid ? : 0;
  314. }
  315. /**
  316. * 场景数据(转数组格式),用于where条件
  317. * @param
  318. * @author Michael_xu
  319. * @return
  320. */
  321. public function dataChangeArray($string)
  322. {
  323. $data_arr = [];
  324. $where = [];
  325. eval('$data_arr = '.$string.';');
  326. foreach ($data_arr as $k=>$v) {
  327. if ($v['state']) {
  328. $address_where[] = '%'.$v['state'].'%';
  329. if ($v['city']) {
  330. $address_where[] = '%'.$v['city'].'%';
  331. if ($v['area']) {
  332. $address_where[] = '%'.$v['area'].'%';
  333. }
  334. }
  335. if ($v['condition'] == 'not_contain') {
  336. $where[$k] = ['notlike', $address_where, 'OR'];
  337. } else {
  338. $where[$k] = ['like', $address_where, 'AND'];
  339. }
  340. } elseif (!empty($v['start']) || !empty($v['end'])) {
  341. if ($v['start'] && $v['end']) {
  342. $where[$k] = ['between',[strtotime($v['start']),strtotime($v['end'])+86399]];
  343. } elseif ($v['start']) {
  344. $where[$k] = ['egt',strtotime($v['start'])];
  345. } else {
  346. $where[$k] = ['elt',strtotime($v['end'])+86399];
  347. }
  348. } elseif (!empty($v['value'])) {
  349. $where[$k] = field($v['value'],$v['condition']);
  350. }
  351. }
  352. return $where ? : [];
  353. }
  354. /**
  355. * 场景排序
  356. * @param ids 场景id数组
  357. * @param hide_ids 隐藏场景id数组
  358. * @author Michael_xu
  359. * @return
  360. */
  361. public function listOrder($param, $user_id)
  362. {
  363. $res = true;
  364. $resHide = true;
  365. //使用
  366. $data = [];
  367. foreach ($param['ids'] as $k=>$v) {
  368. $data[] = ['scene_id' => $v,'order_id' => $k,'update_time' => time(),'user_id' => $user_id,'is_hide' => 0];
  369. }
  370. if ($param['ids']) $res = $this->isUpdate()->saveAll($data);
  371. //隐藏
  372. $hideData = [];
  373. foreach ($param['hide_ids'] as $k=>$v) {
  374. $hideData[] = ['scene_id' => $v,'order_id' => $k,'update_time' => time(),'user_id' => $user_id,'is_hide' => 1];
  375. }
  376. if ($param['hide_ids']) $resHide = $this->isUpdate()->saveAll($hideData);
  377. if ($res == false || $resHide == false) {
  378. $this->error = '设置出错,请重试';
  379. return false;
  380. }
  381. return true;
  382. }
  383. /**
  384. * [getDefaultData 默认场景]
  385. * @param types 分类
  386. * @author Michael_xu
  387. * @return [array]
  388. */
  389. public function getDefaultData($types, $user_id)
  390. {
  391. $where = [];
  392. $where['types'] = $types;
  393. $where['user_id'] = $user_id;
  394. $scene_id = db('admin_scene_default')->where($where)->value('scene_id');
  395. if (!$scene_id && in_array($types,['crm_leads','crm_customer','crm_business','crm_contacts','crm_contract','crm_receivables','crm_visit'])) {
  396. $resData['bydata'] = 'all';
  397. } else {
  398. $resData = db('admin_scene')->where(['scene_id' => $scene_id])->find();
  399. }
  400. if ($resData['bydata']) {
  401. $data = $this->getByData($types, $resData['bydata'], $user_id);
  402. } else {
  403. //处理data
  404. $data = $resData ? json_decode($resData,true) : [];
  405. }
  406. return $data;
  407. }
  408. /**
  409. * [getByData 系统场景数据]
  410. * @param types 分类
  411. * @author Michael_xu
  412. * @return [array]
  413. */
  414. public function getByData($types, $bydata, $user_id)
  415. {
  416. // print_r($types . '--');
  417. // print_r($bydata . '--');
  418. // print_r($user_id);
  419. // exit;
  420. $map = [];
  421. $auth_user_ids = [];
  422. $part_user_ids = [];
  423. switch ($bydata) {
  424. case 'me' :
  425. # 我负责的
  426. $auth_user_ids[] = $user_id;
  427. break;
  428. case 'mePart' :
  429. # 我参与的(即相关团队)
  430. $part_user_ids = $user_id;
  431. break;
  432. case 'sub' :
  433. # 下属负责的
  434. $auth_user_ids = getSubUserId(false) ? : ['-1'];
  435. break;
  436. case 'all' :
  437. # 全部
  438. $auth_user_ids = '';
  439. break;
  440. case 'is_transform' :
  441. # 已转化线索
  442. $map['is_transform'] = ['condition' => 'eq', 'value' => 1, 'form_type' => 'text', 'name' => ''];
  443. break;
  444. case 'pool' :
  445. # 今日进入公海的客户
  446. $customerModel = new \app\crm\model\Customer();
  447. $map = $customerModel->getWhereByToday();
  448. break;
  449. case 'win_business' :
  450. # 赢单的商机
  451. $map['is_end'] = ['condition' => 'eq', 'value' => 1];
  452. break;
  453. case 'fail_business' :
  454. # 输单的商机
  455. $map['is_end'] = ['condition' => 'eq', 'value' => 2];
  456. break;
  457. case 'star' :
  458. $where = $this->getStarParam($types, $user_id);
  459. if (!empty($where)) $map = $where;
  460. break;
  461. default :
  462. # 全部
  463. $auth_user_ids = '';
  464. }
  465. $auth_user_ids = $auth_user_ids ? : [];
  466. if ($auth_user_ids) {
  467. $map['owner_user_id'] = ['condition' => 'in','value' => $auth_user_ids,'form_type' => 'text','name' => ''];
  468. }
  469. if ($part_user_ids) {
  470. $map['ro_user_id'] = $part_user_ids ? : '';
  471. $map['rw_user_id'] = $part_user_ids ? : '';
  472. }
  473. return $map;
  474. }
  475. /**
  476. * 获取我的关注条件
  477. *
  478. * @param $types
  479. * @return array
  480. * @throws \think\db\exception\DataNotFoundException
  481. * @throws \think\db\exception\ModelNotFoundException
  482. * @throws \think\exception\DbException
  483. */
  484. public function getStarParam($types, $user_id)
  485. {
  486. $where = [];
  487. $result = [];
  488. $data = Db::name('crm_star')->field(['target_id'])->where(['user_id' => $user_id, 'type' => 'crm_' . $types])->select();
  489. foreach ($data AS $key => $value) $result[] = $value['target_id'];
  490. if ($types == 'leads') $where['leads_id'] = $result ? ['condition' => 'in', 'value' => implode(',', $result)] : 0;
  491. if ($types == 'customer') $where['customer_id'] = $result ? ['condition' => 'in', 'value' => implode(',', $result)] : 0;
  492. if ($types == 'contacts') $where['contacts_id'] = $result ? ['condition' => 'in', 'value' => implode(',', $result)] : 0;
  493. if ($types == 'business') $where['business_id'] = $result ? ['condition' => 'in', 'value' => implode(',', $result)] : 0;
  494. return $where;
  495. }
  496. /**
  497. * [updateData 跳过验证的编辑]
  498. * @param types 分类
  499. * @author Michael_xu
  500. * @return [array]
  501. */
  502. public function updateData($data, $scene_id)
  503. {
  504. $param['data'] = is_array($data) ? $data : '';
  505. $param['update_time'] = time();
  506. $res = $this->allowField(true)->save($param, ['scene_id' => $scene_id]);
  507. if ($res) {
  508. return true;
  509. } else {
  510. $this->error = '修改失败';
  511. return false;
  512. }
  513. }
  514. }