Activity.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. <?php
  2. namespace app\sys\controller;
  3. use think\facade\View;
  4. use think\facade\Request;
  5. use app\logics\Activity as Logic;
  6. use app\model\Activity as ModelActivity;
  7. use app\model\ActivityCustomerExportLog;
  8. use app\model\Footprints;
  9. use think\facade\Db;
  10. use app\model\Employee;
  11. use app\model\Customer;
  12. use app\model\Org;
  13. use app\model\Permission;
  14. use app\model\Grant;
  15. use app\model\CustomerVisitLog;
  16. class Activity
  17. {
  18. /**
  19. * 列表
  20. */
  21. public function list()
  22. {
  23. if (!Request::isAjax()) {
  24. $eid = ModelActivity::where([['del', '=', 0], ['root_id', '=', request()->employee->root_id], ['employee_id', '>', 0]])->group('employee_id')->column('employee_id');
  25. $where = [
  26. ['id', 'in', $eid],
  27. ['grant_id', '>', 0],
  28. ['root_id', '=', request()->employee->root_id]
  29. ];
  30. // 运营人员列表
  31. $employee = Employee::where($where)->field(['id', 'opt_name as name'])->select()->toArray();
  32. View::assign('employee', $employee);
  33. return View::fetch();
  34. }
  35. $param = Request::only(['page', 'limit', 'keyword', 'date', 'employee_id']);
  36. $where = [
  37. ['del', '=', 0],
  38. ['root_id', '=', request()->employee->root_id]
  39. ];
  40. if (!empty($param['date'])) {
  41. $dates = explode(' - ', $param['date']);
  42. $where[] = ['start_date', '>=', "$dates[0]"];
  43. $where[] = ['end_date', '<=', "$dates[1]"];
  44. }
  45. if (!empty($param['keyword'])) {
  46. $where[] = ['title', 'like', '%' . $param['keyword'] . '%'];
  47. }
  48. if (!empty($param['employee_id'])) {
  49. $where[] = ['employee_id', '=', $param['employee_id']];
  50. }
  51. $list = ModelActivity::with(['employee'])->where($where)->page($param['page'], $param['limit'])->field('*,end_date timestate')->order('addtime desc')->select()->toArray();
  52. $aids = [];
  53. foreach ($list as &$val) {
  54. $val['arr_qrcode_employee_id'] = [];
  55. if (!empty($val['qrcode_employee_id'])) {
  56. $allid = explode(',', $val['qrcode_employee_id']);
  57. $val['arr_qrcode_employee_id'] = $allid;
  58. foreach ($allid as $k => $v) {
  59. $aids[] = $v;
  60. }
  61. }
  62. }
  63. $qrcode = Employee::where([['id', 'in', array_unique($aids)]])->column('name', 'id');
  64. //$qrcode = Employee::where([['id', 'in', array_column($list, 'qrcode_employee_id')]])->column('name', 'id');
  65. foreach ($list as $k => $v) {
  66. $qrcode_name = '';
  67. foreach ($qrcode as $r => $e) {
  68. if (in_array($r, $v['arr_qrcode_employee_id'])) {
  69. $qrcode_name .= $e . ',';
  70. }
  71. }
  72. $list[$k]['qrcode_name'] = isset($qrcode_name) ? trim($qrcode_name, ',') : '';
  73. }
  74. $count = ModelActivity::where($where)->count();
  75. //邀约客户
  76. if ($list) {
  77. $aids = array_column($list, 'id');
  78. $v_where[] = ['state', 'in', CustomerVisitLog::changeState('预约活动', 'chaos')];
  79. $v_where[] = ['aid', 'in', $aids];
  80. $footprints = CustomerVisitLog::withJoin('customer')->where([
  81. ['customer_visit_log.state', 'in', CustomerVisitLog::changeState('预约活动', 'chaos')],
  82. ['customer_visit_log.aid', 'in', $aids]
  83. ])->group('customer_visit_log.aid,customer_visit_log.customer_id')->column('customer_visit_log.aid as aid,customer_visit_log.customer_id as customer_id');
  84. $arr = [];
  85. foreach ($footprints as $k => $v) {
  86. $arr[$v['aid']] = isset($arr[$v['aid']]) ? $arr[$v['aid']] += 1 : 1;
  87. }
  88. foreach ($list as $k => $v) {
  89. $list[$k]['user_count'] = isset($arr[$v['id']]) ? $arr[$v['id']] : 0;
  90. }
  91. }
  92. return json(['code' => 0, 'data' => $list, 'count' => $count, 'msg' => '获取成功']);
  93. }
  94. /**
  95. * 添加视图
  96. */
  97. public function add()
  98. {
  99. if (request()->isAjax()) return $this->addActivity();
  100. $root_id = request()->employee->root_id;
  101. //扫码人员
  102. $employee = Employee::where([['uid', '>', 0], ['state', '=', '在职'], ['root_id', '=', $root_id]])->column('id,name');
  103. View::assign('employee', $employee);
  104. return View::fetch();
  105. }
  106. /**
  107. * 添加活动
  108. */
  109. public function addActivity()
  110. {
  111. $data = Request::only(['title', 'content', 'type', 'cover', 'money', 'start_date', 'end_date', 'wxmch', 'cate', 'poster', 'address', 'qrcode_employee_id']);
  112. $data['root_id'] = request()->employee->root_id;
  113. $data['employee_id'] = request()->employee->id;
  114. if ($data['start_date'] > $data['end_date']) return json(['code' => 1, 'msg' => '开始日期需在结束日期之前']);
  115. $data['qrcode_employee_id'] .= ',';
  116. ModelActivity::insert($data);
  117. return json(['code' => 0, 'msg' => '添加成功']);
  118. }
  119. /**
  120. * 修改视图
  121. */
  122. public function edit($id)
  123. {
  124. $edit = (new ModelActivity())->where([
  125. 'id' => $id, 'root_id' => request()->employee->root_id
  126. ])->find();
  127. $edit->coverc = $edit->getData('cover');
  128. $edit->posterc = $edit->getData('poster');
  129. View::assign('data', $edit);
  130. $root_id = request()->employee->root_id;
  131. //扫码人员
  132. $employee = Employee::where([['uid', '>', 0], ['state', '=', '在职'], ['root_id', '=', $root_id]])->column('id,name');
  133. View::assign('employee', $employee);
  134. return View::fetch();
  135. }
  136. //获取扫码人员
  137. public function get_qrcode_employee()
  138. {
  139. $data = Request::only(['id']);
  140. if (!empty($data['id'])) {
  141. $actdata = ModelActivity::where([
  142. 'id' => $data['id'], 'root_id' => request()->employee->root_id
  143. ])->find();
  144. } else {
  145. $actdata = ModelActivity::where([
  146. ['root_id', '=', request()->employee->root_id], ['qrcode_employee_id', '<>', 0], ['qrcode_employee_id', '<>', '']
  147. ])->order('id desc')->find();
  148. }
  149. $arr_qrcode_emp = [];
  150. if (!empty($actdata['qrcode_employee_id'])) {
  151. $arr_qrcode_emp = explode(',', $actdata['qrcode_employee_id']);
  152. }
  153. $employee = Employee::where([['uid', '>', 0], ['state', '=', '在职'], ['root_id', '=', request()->employee->root_id]])->field('id,name')->select()->toArray();
  154. foreach ($employee as &$val) {
  155. $val['isshow'] = 0;
  156. if (in_array($val['id'], $arr_qrcode_emp)) {
  157. $val['isshow'] = 1;
  158. }
  159. }
  160. return json(['code' => 0, 'msg' => '获取成功', 'data' => $employee]);
  161. }
  162. /**
  163. * 添加活动
  164. */
  165. public function editActivity()
  166. {
  167. $data = Request::only(['id', 'title', 'content', 'type', 'cover', 'money', 'start_date', 'end_date', 'wxmch', 'ycover', 'yposter', 'poster', 'address', 'cate', 'qrcode_employee_id']);
  168. // if ($data['type'] == 1) $data['money'] = 0;
  169. if ($data['start_date'] > $data['end_date']) return json(['code' => 1, 'msg' => '开始日期需在结束日期之前']);
  170. $data['qrcode_employee_id'] .= ',';
  171. // if (!isset($data['cover']) && ) {unset($data['cover']);}
  172. // if (!$data['poster'] && isset($data['poster'])) {unset($data['poster']);}
  173. $obj = (new ModelActivity())->where(['id' => $data['id'], 'root_id' => request()->employee->root_id])->find();
  174. if (empty($obj)) return json(['code' => 1, 'msg' => '数据不存在']);
  175. $obj->save($data);
  176. return json(['code' => 0, 'msg' => '修改成功']);
  177. }
  178. /**
  179. * 是否展示
  180. */
  181. public function show($id)
  182. {
  183. $obj = (new ModelActivity())->where(['id' => $id, 'root_id' => request()->employee->root_id])->find();
  184. if (empty($obj)) return json(['code' => 1, 'msg' => '数据不存在']);
  185. $obj->show = $obj->show == 1 ? 0 : 1;
  186. $obj->save();
  187. return json(['code' => 0, 'msg' => '修改成功']);
  188. }
  189. /**
  190. * 删除
  191. */
  192. public function del($id)
  193. {
  194. (new ModelActivity())->where(['id' => $id, 'root_id' => request()->employee->root_id])->update(['del' => 1]);
  195. return json(['code' => 0, 'msg' => '删除成功']);
  196. }
  197. /*
  198. * 富文本图片
  199. */
  200. public function imgUpload()
  201. {
  202. $bindUrl = config('app.ali_oss_bindurl');
  203. $data = [
  204. 'src' => 'http://' . $bindUrl . '/' . Request::param('file'),
  205. 'title' => ''
  206. ];
  207. return json(['code' => 0, 'msg' => '', 'data' => $data]);
  208. }
  209. /**
  210. * 活动客户
  211. */
  212. public function customer()
  213. {
  214. $id = input('id', 0);
  215. if (!Request::isAjax()) {
  216. $org = Org::where([['path', 'like', request()->employee->root_id . '-%']])->field('id,name')->select()->toArray();
  217. View::assign('org', $org);
  218. View::assign('id', $id);
  219. //数据统计
  220. // 活动统计:从员工、基层管理、高层管理的维度统计。
  221. // 从客户的角度统计:邀约客户、到场客户、领礼品客户、收定、签单等
  222. $data = [
  223. 'dd' => CustomerVisitLog::changeState('已到店', 'chaos'),
  224. 'qd' => CustomerVisitLog::changeState('已签单', 'chaos'),
  225. 'jd' => CustomerVisitLog::changeState('已交定', 'chaos'),
  226. 'dc' => CustomerVisitLog::changeState('已到场', 'chaos'),
  227. 'yy' => CustomerVisitLog::changeState('预约活动', 'chaos'),
  228. ];
  229. foreach ($data as $k => $value) {
  230. $rs = CustomerVisitLog::withJoin('customer')->where([
  231. ['customer_visit_log.aid', '=', $id],
  232. ['customer.org_id', 'in', array_column($org, 'id')],
  233. ['customer_visit_log.state', 'in', $value]
  234. ])->group('customer_visit_log.customer_id')->field('customer_visit_log.customer_id')->column('customer_visit_log.customer_id');
  235. $data[$k] = count($rs);
  236. }
  237. view::assign('data', $data);
  238. View::assign('id', $id);
  239. View::assign('cate', input('cate') ?? 0);
  240. return View::fetch();
  241. }
  242. $param = request()->param(['type'=>0, 'org'=>'', 'page'=>1, 'limit'=>30]);
  243. // 数据导出
  244. $w[] = ['aid', '=', $id];
  245. $type = ['预约活动', '已到店', '确认到场', '交定', '签单'];
  246. $w[] = CustomerVisitLog::changeState(['state', '=', $type[$param['type']]]);
  247. $cidList = CustomerVisitLog::where($w)->group('customer_id')->column('max(addtime)', 'customer_id');
  248. $aw[] = ['id', 'in', array_keys($cidList)];
  249. if (isset($param['org']) && !empty($param['org'])) {
  250. $ew[] = ['root_id', '=', request()->employee->root_id];
  251. $ew[] = ['org_id', '=', $param['org']];
  252. $eids = Employee::where($ew)->column('id');
  253. $aw[] = ['employee_id|designer_id', 'in', $eids];
  254. }
  255. $count = Customer::where($aw)->count();
  256. $res = Customer::with(['User', 'employee', 'org'])->where($aw)->order('revisit_time desc,id desc')->visible(['id', 'state', 'revisit_time', 'name', 'User.headimgurl', 'sex', 'community_name', 'level', 'employee.name', 'employee_id', 'org_name'])->order('id desc')->page($param['page'], $param['limit'])->select()->toArray();
  257. foreach($res as &$v){
  258. $v['invis_time'] = $cidList[$v['id']];
  259. $v['e_name'] = isset($v['employee']) ? $v['employee']['name'] : '';
  260. }
  261. return json(['code' => 0, 'data' => $res, 'count' => $count, 'msg' => '获取成功']);
  262. }
  263. //排行榜
  264. public function ranking()
  265. {
  266. $id = input('id', 0);
  267. view::assign('id', $id);
  268. $org = Org::where([['path', 'like', request()->employee->root_id . '-%']])->field('id,name,level')->order('path asc')->select()->toArray();
  269. view::assign('org', $org);
  270. // 活动统计:从员工、基层管理、高层管理的维度统计。
  271. // 从客户的角度统计:邀约客户、到场客户、领礼品客户、收定、签单等
  272. $token = request()->employee;
  273. // $tw[] = ['aid','=',$id];
  274. // if ($token->is_manager==1) {//查看全公司数据
  275. $org = Org::where([['path', 'like', $token->root_id . '-%']])->column('id');
  276. $tw[] = ['org_id', 'in', $org];
  277. $eids = Employee::where($tw)->column('id');
  278. $w[] = ['employee_id', 'in', $eids];
  279. // }elseif ($token->is_manager) {//管理员查看部门数据
  280. // }else{//员工查看个人数据
  281. // $w[] = ['employee_id','=',$token->id];
  282. // }
  283. $w[] = ['aid', '=', $id];
  284. $data['yy'] = $data['dc'] = $data['jd'] = $data['qd'] = 0;
  285. $res = CustomerVisitLog::where($w)->field('state')->select()->toArray();
  286. foreach ($res as $k => $v) {
  287. if ($v['state'] == '预约活动') {
  288. $data['yy'] += 1;
  289. } elseif ($v['state'] == '已到场') {
  290. $data['dc'] += 1;
  291. } elseif ($v['state'] == '已交定') {
  292. $data['jd'] += 1;
  293. } elseif ($v['state'] == '已签单') {
  294. $data['qd'] += 1;
  295. }
  296. }
  297. view::assign('data', $data);
  298. return View::fetch();
  299. }
  300. //排行榜数据
  301. public function ranking_list()
  302. {
  303. $param = input('');
  304. if ($param['cate'] == 2) {
  305. $data = $this->ranking_org($param);
  306. } else {
  307. $data = $this->ranking_person($param);
  308. }
  309. return $data;
  310. }
  311. /*
  312. * 公司/团队 排行榜
  313. * auth kjl
  314. * date 2022/01/11
  315. * type 从活动客户状态分为:邀约、到场、收定、签单
  316. * cate 0公司排行,2部门排行
  317. */
  318. public function ranking_person($data)
  319. {
  320. $token = request()->employee;
  321. $param = $data;
  322. //0邀约,1到场,2交定,3签单
  323. if ($param['type'] == 1) {
  324. $cw[] = CustomerVisitLog::changeState(['state', '=', '确认到场']);
  325. } elseif ($param['type'] == 2) {
  326. $cw[] = CustomerVisitLog::changeState(['state', '=', '交定']);
  327. } elseif ($param['type'] == 3) {
  328. $cw[] = CustomerVisitLog::changeState(['state', '=', '签单']);
  329. } else {
  330. $cw[] = CustomerVisitLog::changeState(['state', '=', '预约活动']);
  331. }
  332. $w[] = ['root_id', '=', $token->root_id];
  333. if ($param['cate'] == 2) {
  334. $w[] = ['org_id', '=', $token->org_id];
  335. } elseif ($param['cate'] == 0 && $param['org']) {
  336. $w[] = ['org_id', '=', $param['org']];
  337. }
  338. $w[] = ['state', '=', '在职'];
  339. $w[] = ['uid', '>', 0];
  340. $eid = Employee::with(['org'])->where($w)->visible(['org_id', 'name', 'id', 'org.name'])->select()->toArray();
  341. $cw[] = ['employee_id', 'in', array_column($eid, 'id')];
  342. $cw[] = ['aid', '=', $param['id']];
  343. $list = CustomerVisitLog::where($cw)->group('employee_id,customer_id')->field('employee_id,customer_id')->select()->toArray();
  344. $res = [];
  345. foreach ($list as $k => $v) {
  346. $res[$v['employee_id']] = isset($res[$v['employee_id']]) ? $res[$v['employee_id']] += 1 : 1;
  347. }
  348. foreach ($eid as $k2 => $v2) {
  349. $eid[$k2]['count'] = isset($res[$v2['id']]) ? $res[$v2['id']] : 0;
  350. }
  351. array_multisort(array_column($eid, 'count'), SORT_DESC, $eid);
  352. $count = count($eid);
  353. $eid = array_slice($eid, ($param['page'] - 1) * $param['limit'], $param['limit']);
  354. foreach ($eid as $k3 => $v3) {
  355. $eid[$k3]['ranking'] = ($param['page'] - 1) * $param['limit'] + 1 + $k3;
  356. $eid[$k3]['org'] = $v3['org'] ? $v3['org']['name'] : '';
  357. }
  358. return json(['code' => 0, 'data' => $eid, 'count' => $count, 'msg' => '获取成功']);
  359. }
  360. /*
  361. * 团队排行榜
  362. * auth kjl
  363. * date 2022/01/11
  364. * id活动id,type邀约,到访,收订,签单,eid,p,pagesize,org_id
  365. */
  366. public function ranking_org($data)
  367. {
  368. $token = request()->employee;
  369. $param = $data;
  370. //0邀约,1到场,2交定,3签单
  371. if ($param['type'] == 1) {
  372. $cw[] = CustomerVisitLog::changeState(['state', '=', '已到场']);
  373. } elseif ($param['type'] == 2) {
  374. $cw[] = CustomerVisitLog::changeState(['state', '=', '已交定']);
  375. } elseif ($param['type'] == 3) {
  376. $cw[] = CustomerVisitLog::changeState(['state', '=', '已签单']);
  377. } else {
  378. $cw[] = CustomerVisitLog::changeState(['state', '=', '预约活动']);
  379. }
  380. $org = Org::where([['path', 'like', $token->root_id . '-%']])->field('name,id')->select()->toArray();
  381. $eids = Employee::where([['root_id', '=', $token['root_id']], ['state', '=', '在职'], ['uid', '>', 0]])->column('org_id', 'id');
  382. $cw[] = ['employee_id', 'in', array_keys($eids)];
  383. $cw[] = ['aid', '=', $param['id']];
  384. $list = CustomerVisitLog::with(['employee'])->where($cw)->group('employee_id,customer_id')->visible(['org_id', 'customer_id', 'employee.org_id'])->select()->toArray();
  385. $res = [];
  386. foreach ($list as $k => $v) {
  387. $res[$v['employee']['org_id']] = isset($res[$v['employee']['org_id']]) ? $res[$v['employee']['org_id']] += 1 : 1;
  388. }
  389. foreach ($org as $k2 => $v2) {
  390. $org[$k2]['count'] = isset($res[$v2['id']]) ? $res[$v2['id']] : 0;
  391. }
  392. array_multisort(array_column($org, 'count'), SORT_DESC, $org);
  393. $count = count($res);
  394. $org = array_slice($org, ($param['page'] - 1) * $param['limit'], $param['limit']);
  395. foreach ($org as $k3 => $v3) {
  396. $org[$k3]['org'] = $v3['name'];
  397. $org[$k3]['ranking'] = ($param['page'] - 1) * $param['limit'] + 1 + $k3;
  398. }
  399. return json(['code' => 0, 'data' => $org, 'count' => $count, 'msg' => '获取成功']);
  400. }
  401. /*
  402. * 手动结束
  403. * auth kjl
  404. * date 2022/04/07
  405. * id活动id
  406. */
  407. public function end($id)
  408. {
  409. $info = ModelActivity::where('id', $id)->find()->toArray();
  410. $date = $info['end_date'] > date('Y-m-d', strtotime('-1 day')) ? date('Y-m-d', strtotime('-1 day')) : $info['end_date'];
  411. ModelActivity::where('id', $id)->update(['end_date' => $date]);
  412. return json(['code' => 0, 'data' => '', 'msg' => '修改成功']);
  413. }
  414. /**
  415. * 部门人员树
  416. * @param $data
  417. * @param int $pid
  418. * @param $persons
  419. * @return array
  420. */
  421. public function tree($data, $pid = 0, $persons)
  422. {
  423. $new_arr = [];
  424. foreach ($data as $k => $v) {
  425. if ($v['pid'] == $pid) {
  426. $persions = isset($persons[$v['id']]) ? $persons[$v['id']] : [];
  427. $children = $this->tree($data, $v['id'], $persons);
  428. $v['children'] = array_merge_recursive($children, $persions);
  429. if (empty($v['children'])) $v['disabled'] = true;
  430. $new_arr[] = $v;
  431. }
  432. }
  433. return $new_arr;
  434. }
  435. /**
  436. * 指派人员
  437. * @param $id
  438. */
  439. public function get_person($id)
  440. {
  441. $ids = input('id', '');
  442. $root_id = request()->employee->root_id;
  443. $keyword = input('keyword', '');
  444. //所有员工
  445. $w1[] = ['root_id', '=', $root_id];
  446. $w1[] = ['state', '=', '在职'];
  447. $w1[] = ['org_id', '>', 0];
  448. $w1[] = ['uid', '>', 0];
  449. if ($keyword) {
  450. $w1[] = ['name', 'like', '%' . $keyword . '%'];
  451. }
  452. $employee = Employee::where($w1)->field('id,name title,org_id,is_manager')->order('is_manager desc,id desc')->select()->toArray();
  453. if ($ids) {
  454. $ids = explode(',', $ids);
  455. foreach ($employee as $k => &$v) {
  456. $v['selected'] = in_array($v['id'], $ids);
  457. $v['children'] = [];
  458. $v['title'] = $v['is_manager'] ? $v['title'] . '(负责人)' : $v['title'];
  459. $v['org_class'] = 'org_' . $v['org_id'];
  460. $v['per_class'] = 'per_' . $v['id'];
  461. $v['type'] = 'per';
  462. }
  463. } else {
  464. foreach ($employee as $k => &$v) {
  465. $v['selected'] = false;
  466. $v['children'] = [];
  467. $v['all_count'] = 0;
  468. $v['title'] = $v['is_manager'] ? $v['title'] . '(负责人)' : $v['title'];
  469. $v['org_class'] = 'org_' . $v['org_id'];
  470. $v['per_class'] = 'per_' . $v['id'];
  471. $v['type'] = 'per';
  472. }
  473. }
  474. $persons = [];
  475. foreach ($employee as $k => $v1) {
  476. $persons[$v1['org_id']][] = $v1;
  477. }
  478. $where = [
  479. ['path', 'like', $root_id . '-%'],
  480. ['status', '=', 1]
  481. ];
  482. $count = Employee::where([['root_id', '=', $root_id], ['state', '=', '在职'], ['uid', '>', 0]])->group('org_id')->column('count(*) count', 'org_id');
  483. $allnodes = Org::where($where)->field('id,pid,name title,level,org_type,info,path')->order('level asc, id asc')->select()->toarray();
  484. foreach ($allnodes as $k => $v) {
  485. $allnodes[$k]['count'] = isset($count[$v['id']]) ? $count[$v['id']] : 0; //本部门人数
  486. $allnodes[$k]['all_count'] = 0; //包含子部门总数
  487. $allnodes[$k]['org_class'] = 'org_' . $v['id'];
  488. $allnodes[$k]['per_class'] = 'per_org_' . $v['id'];
  489. $allnodes[$k]['type'] = 'org';
  490. foreach ($allnodes as $k2 => $v2) {
  491. if (strpos($v2['path'], $v['path']) !== false) {
  492. $allnodes[$k]['all_count'] = isset($count[$v2['id']]) ? $count[$v2['id']] + $allnodes[$k]['all_count'] : $allnodes[$k]['all_count'];
  493. }
  494. }
  495. $allnodes[$k]['title'] = $allnodes[$k]['title'] . ' (' . $allnodes[$k]['all_count'] . ')';
  496. }
  497. $tree = $this->tree($allnodes, 0, $persons);
  498. $info = ModelActivity::where(['root_id' => request()->employee->root_id, 'id' => $id])->value('assign_employee');
  499. return json(['code' => 0, 'data' => $tree, 'checkOrg' => $info]);
  500. }
  501. /**
  502. * 活动指派
  503. */
  504. public function activity_assign()
  505. {
  506. if (!request()->isAjax()) {
  507. $id = input('id', '', 'intval');
  508. View::assign('id', $id);
  509. $assign_employee = ModelActivity::where(['root_id' => request()->employee->root_id, 'id' => $id])->value('assign_employee');
  510. $count = $assign_employee ? count(explode(',', $assign_employee)) : 0;
  511. view::assign('count', $count);
  512. return View::fetch();
  513. }
  514. $id = input('id', '', 'intval');
  515. $pid = input('pid', '', 'trim'); //多选框选中id
  516. $type = input('type', '', 'trim'); //选中类型,人/部门
  517. $res = input('res', '', 'trim'); //选择结果 1选中,0取消
  518. $data = [];
  519. $assign_employee = ModelActivity::where(['root_id' => request()->employee->root_id, 'id' => $id])->value('assign_employee');
  520. $a = 0;
  521. if ($type == 'per' && $pid) {
  522. $data[] = 'per_' . $pid;
  523. $pid = [$pid];
  524. $a = 1;
  525. } elseif ($type == 'org' && $pid) {
  526. $data[] = 'org_' . $pid;
  527. $org = Org::where([['id', '=', $pid]])->value('path');
  528. $orgs = Org::where([['path', 'like', $org . '%']])->column('id');
  529. $pid = Employee::where([['root_id', '=', request()->employee->root_id], ['org_id', 'in', $orgs], ['state', '=', '在职'], ['uid', '>', 0]])->order('is_manager desc,id desc')->column('id');
  530. $a = 1;
  531. foreach ($pid as $v) {
  532. $data[] = 'per_' . $v;
  533. }
  534. foreach ($orgs as $v2) {
  535. $data[] = 'org_' . $v2;
  536. }
  537. }
  538. $assign_employee = explode(',', $assign_employee);
  539. if ($a) {
  540. $arr = array_filter(array_diff($assign_employee, $pid));
  541. $arr = $res ? array_merge($pid, $arr) : $arr;
  542. $arr = array_unique($arr);
  543. //过滤运营人员,旧bug导致选择根部门时,运营人员也会在内
  544. $arr = Employee::where([['id', 'in', $arr], ['uid', '>', 0], ['state', '=', '在职']])->column('id');
  545. //查询指派人的组织
  546. $employee_org = Employee::where('id', 'in', $arr)->group('org_id')->column('org_id');
  547. $employee_org = implode(',', $employee_org);
  548. ModelActivity::where(['root_id' => request()->employee->root_id, 'id' => $id])->update(['assign_org_id' => $employee_org, 'assign_employee' => implode(',', $arr)]);
  549. }
  550. return json(['code' => 0, 'data' => $data]);
  551. }
  552. /*
  553. * 指派展示列表
  554. */
  555. public function activity_assign_list()
  556. {
  557. $id = input('id', '', 'intval');
  558. $page = input('page', 1, 'intval');
  559. $limit = input('limit', 10, 'intval');
  560. $keyword = input('keyword', '', 'trim');
  561. if ($keyword) {
  562. $w[] = ['name', 'like', '%' . $keyword . '%'];
  563. }
  564. $arr = ModelActivity::where(['root_id' => request()->employee->root_id, 'id' => $id])->value('assign_employee');
  565. $arr = $arr ? explode(',', $arr) : [];
  566. $w[] = ['id', 'in', $arr];
  567. $w[] = ['state', '=', '在职'];
  568. $w[] = ['uid', '>', 0];
  569. $data = Employee::with('orgName')->where($w)->visible(['name', 'org_name', 'id', 'is_manager'])->select()->toArray();
  570. $count = count($data);
  571. $arr = array_flip($arr);
  572. foreach ($data as $k => $v) {
  573. $data[$k]['order'] = $arr[$v['id']];
  574. }
  575. array_multisort($data, SORT_ASC, array_column($data, 'order'));
  576. foreach ($data as $k => $v) {
  577. $data[$k]['xh'] = $k + 1;
  578. }
  579. $data = array_slice($data, ($page - 1) * $limit, $limit);
  580. return json(['code' => 0, 'data' => $data, 'count' => $count]);
  581. }
  582. /**
  583. * 删除指派
  584. * @return \think\response\Json
  585. */
  586. public function del_assign()
  587. {
  588. $id = input('id', '', 'intval');
  589. $eid = input('eid', '', 'intval');
  590. if ($id && $eid) {
  591. if ($eid == -1) {
  592. ModelActivity::where(['root_id' => request()->employee->root_id, 'id' => $id])->update(['assign_employee' => '', 'assign_org_id' => '']);
  593. } else {
  594. $arr = ModelActivity::where(['root_id' => request()->employee->root_id, 'id' => $id])->value('assign_employee');
  595. $arr = array_filter(array_diff(explode(',', $arr), [$eid]));
  596. $data = [];
  597. if (empty($arr)) {
  598. $data['assign_employee'] = '';
  599. $data['assign_org_id'] = '';
  600. } else {
  601. $data['assign_employee'] = implode(',', $arr);
  602. $assign_org_id = Employee::where('id', 'in', $arr)->group('org_id')->column('org_id');
  603. $data['assign_org_id'] = implode(',', $assign_org_id);
  604. }
  605. ModelActivity::where(['root_id' => request()->employee->root_id, 'id' => $id])->update($data);
  606. }
  607. }
  608. return json(['code' => 0, 'data' => '取消成功', 'msg' => '取消成功']);
  609. }
  610. /**
  611. * 导出操作
  612. */
  613. public function export()
  614. {
  615. $param = request()->param(['org', 'type', 'id']);
  616. $op = request()->employee;
  617. // 数据导出
  618. $w[] = ['aid', '=', $param['id']];
  619. $type = ['预约活动', '已到店', '确认到场', '交定', '签单'];
  620. $w[] = CustomerVisitLog::changeState(['state', '=', $type[$param['type']]]);
  621. $cidList = CustomerVisitLog::where($w)->group('customer_id')->column('max(addtime)', 'customer_id');
  622. $aw[] = ['id', 'in', array_keys($cidList)];
  623. if ($param['org']) {
  624. $ew[] = ['root_id', '=', request()->employee->root_id];
  625. $ew[] = ['org_id', '=', $param['org']];
  626. $eids = Employee::where($ew)->column('id');
  627. $aw[] = ['employee_id|designer_id', 'in', $eids];
  628. }
  629. $count = Customer::where($aw)->count();
  630. if ($count == 0) return json(['code' => 1, 'msg' => '没有可导出的数据']);
  631. $filename = uniqid();
  632. // 创建导出记录
  633. $log = [
  634. 'type' => $param['type'],
  635. 'org_id' => $param['org'],
  636. 'root_id' => $op->root_id,
  637. 'op_employee' => $op->id,
  638. 'file' => $filename,
  639. 'activity_id' => $param['id']
  640. ];
  641. $log = ActivityCustomerExportLog::create($log);
  642. json(['code' => 0, 'msg' => '导出中'], 200, ['Content-Type' => 'application/json'])->send();
  643. $log->state = 1;
  644. $log->save();
  645. $res = Customer::with(['User', 'employee', 'org'])->where($aw)->order('revisit_time desc,id desc')->visible(['id', 'state', 'revisit_time', 'name', 'User.headimgurl', 'sex', 'community_name', 'level', 'employee.name', 'employee_id', 'org_name'])->order('id desc')->select()->toArray();
  646. $title = ['客户姓名', '客户等级', '客户状态', '跟踪人员', '所属部门', '邀约时间'];
  647. $fp = fopen('../download/' . $filename . '.csv', 'w');
  648. fputcsv($fp, $title);
  649. foreach ($res as $v) {
  650. $row = [
  651. $v['name'],
  652. $v['level'],
  653. $v['state'] ?: '待确认',
  654. isset($v['employee']['name']) ? $v['employee']['name'] : '',
  655. $v['org_name'],
  656. $cidList[$v['id']]
  657. ];
  658. fputcsv($fp, $row);
  659. }
  660. fclose($fp);
  661. // 上传oss
  662. $rs = ossUpload('activityExport/' . $filename . '.csv', '../download/' . $filename . '.csv');
  663. if (!$rs) {
  664. trace('文件上传失败', 'error');
  665. $log->state = -1;
  666. $log->save();
  667. } else {
  668. unlink('../download/' . $filename . '.csv');
  669. $log->state = 2;
  670. $log->save();
  671. }
  672. }
  673. /**
  674. * 导出记录
  675. */
  676. public function exportlog($id)
  677. {
  678. if (!request()->isAjax()) {
  679. view::assign('id', $id);
  680. return View::fetch();
  681. }
  682. $op = request()->employee;
  683. $page = input('page', 1);
  684. $logs = ActivityCustomerExportLog::with(['employee', 'org'])->where(['root_id' => $op->root_id, 'activity_id' => $id])->order('addtime desc')->page($page, 20)->select();
  685. $data = [];
  686. foreach ($logs as $item) {
  687. $data[] = [
  688. 'addtime' => $item->addtime,
  689. 'op' => $item->employee->opt_name ?? '',
  690. 's' => ($item->org ? $item->org->name . ',' : '') . $item->type,
  691. 'file' => $item->file,
  692. 'state' => $item->state
  693. ];
  694. }
  695. $count = ActivityCustomerExportLog::where(['root_id' => $op->root_id, 'activity_id' => $id])->count();
  696. return json(['code' => 0, 'data' => $data, 'pages' => ceil($count / 20)]);
  697. }
  698. }