Massager.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. <?php
  2. namespace app\admin\controller\massager;
  3. use app\admin\model\Area;
  4. use app\admin\model\FastChatServiceUser;
  5. use app\api\model\massager\Wallet;
  6. use app\api\model\system\Message;
  7. use app\api\service\MassagerActionService;
  8. use app\api\service\MassagerService;
  9. use app\api\service\TencentCloudService;
  10. use app\common\controller\Backend;
  11. use redis\RedLock;
  12. use think\Db;
  13. use think\exception\PDOException;
  14. use think\exception\ValidateException;
  15. /**
  16. * 助教管理
  17. *
  18. * @icon fa fa-circle-o
  19. */
  20. class Massager extends Backend
  21. {
  22. protected $noNeedRight = ["check", "duration", "wallet", "interiorScore"];
  23. /**
  24. * Massager模型对象
  25. * @var \app\admin\model\massager\Massager
  26. */
  27. protected $model = null;
  28. public function _initialize()
  29. {
  30. parent::_initialize();
  31. $this->model = new \app\admin\model\massager\Massager;
  32. $this->view->assign("genderList", $this->model->getGenderList());
  33. $this->view->assign("levelList", $this->model->getLevelList());
  34. $this->view->assign("statusList", $this->model->getStatusList());
  35. $typeList = $this->model->getTypeList();
  36. $admin = $this->auth->getUserInfo();
  37. if ($admin && \E_ADMIN_TYPE::Store === $admin["type"]) {
  38. $typeList = ['store' => __('Store')];
  39. }
  40. $this->view->assign("typeList", $typeList);
  41. }
  42. private function fetchWhere()
  43. {
  44. $admin = $this->auth->getUserInfo();
  45. if (!$admin)
  46. $this->error("error");
  47. $p_where = [];
  48. if (\E_ADMIN_TYPE::Store === $admin["type"]) {
  49. array_push($p_where, ["massager.store_id", "=", $admin["store_id"]]);
  50. } else if (\E_ADMIN_TYPE::Agency === $admin["type"]) {
  51. array_push($p_where, ["massager.city_code", "in", is_null($admin["city_codes"]) ? [] : explode(",", $admin["city_codes"])]);
  52. }
  53. return $p_where;
  54. }
  55. /**
  56. * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
  57. * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
  58. * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
  59. */
  60. /**
  61. * 查看
  62. */
  63. public function index()
  64. {
  65. //当前是否为关联查询
  66. $this->relationSearch = true;
  67. //设置过滤方法
  68. $this->request->filter(['strip_tags', 'trim']);
  69. $c_where = $this->fetchWhere();
  70. if ($this->request->isAjax()) {
  71. //如果发送的来源是Selectpage,则转发到Selectpage
  72. if ($this->request->request('keyField')) {
  73. return $this->c_selectpage($c_where);
  74. }
  75. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  76. $query = $this->model
  77. ->with(['store', 'parent'])
  78. ->where($where);
  79. foreach ($c_where as $item) {
  80. $query->where($item[0], $item[1], $item[2]);
  81. }
  82. $list = $query
  83. ->order($sort, $order)
  84. ->paginate($limit);
  85. foreach ($list as $row) {
  86. $row->visible(['id_card_images', 'real_name_auth', 'health_image', 'police_certificate_image', 'emergency_contact_name', 'emergency_contact_mobile', 'emergency_contact_relation', 'wechat_no', 'id', 'name', 'photo_images', 'gender', 'date_of_birth', 'status', 'type', 'service_ids', 'free_travel', 'weight', 'updatetime', 'interior_score', 'negative_count', 'fixed_profit_rate']);
  87. $row->visible(['store']);
  88. $row->getRelation('store')->visible(['name']);
  89. $row->visible(['parent']);
  90. $row->getRelation('parent')->visible(['name']);
  91. }
  92. $result = array("total" => $list->total(), "rows" => $list->items());
  93. return json($result);
  94. }
  95. return $this->view->fetch();
  96. }
  97. public function add()
  98. {
  99. if (false === $this->request->isPost()) {
  100. return $this->view->fetch();
  101. }
  102. $params = $this->request->post('row/a');
  103. if (empty($params)) {
  104. $this->error(__('Parameter %s can not be empty', ''));
  105. }
  106. $params = $this->preExcludeFields($params);
  107. if (isset($params["fixed_profit_rate"])) {
  108. if ($params["fixed_profit_rate"] < 0 || $params["fixed_profit_rate"] > 90)
  109. $this->error("固定分润比例必须在0~90之间");
  110. }
  111. if (isset($params["area_id"]) && $params["area_id"] > 0) {
  112. $area = (new Area())->where([
  113. "id" => $params["area_id"],
  114. "use" => 1,
  115. "level" => 2,
  116. ])->find();
  117. if (!$area)
  118. $this->error("地区选择不正确");
  119. $params["city_code"] = $area["area_code"];
  120. $params["lng"] = $area["lng"];
  121. $params["lat"] = $area["lat"];
  122. } else {
  123. $this->error("地区选择不正确");
  124. }
  125. if (strlen($params["password"]) == 0)
  126. unset($params["password"]);
  127. else
  128. $params["password"] = md5($params["password"]);
  129. if (!isset($params["mobile"]) || strlen($params["mobile"]) !== 11)
  130. $this->error("手机号码错误");
  131. $m = $this->model->where("mobile", $params["mobile"])->find();
  132. if ($m) {
  133. $this->error("手机号码已经存在!");
  134. }
  135. if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
  136. $params[$this->dataLimitField] = $this->auth->id;
  137. }
  138. $result = false;
  139. Db::startTrans();
  140. try {
  141. //是否采用模型验证
  142. if ($this->modelValidate) {
  143. $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
  144. $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
  145. $this->model->validateFailException()->validate($validate);
  146. }
  147. $result = $this->model->allowField(true)->save($params);
  148. Db::commit();
  149. } catch (ValidateException | PDOException | Exception $e) {
  150. Db::rollback();
  151. $this->error($e->getMessage());
  152. }
  153. if ($result === false) {
  154. $this->error(__('No rows were inserted'));
  155. }
  156. $this->success();
  157. }
  158. public function edit($ids = null)
  159. {
  160. $row = $this->model->get($ids);
  161. if (!$row) {
  162. $this->error(__('No Results were found'));
  163. }
  164. $adminIds = $this->getDataLimitAdminIds();
  165. if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
  166. $this->error(__('You have no permission'));
  167. }
  168. if (false === $this->request->isPost()) {
  169. $this->view->assign('row', $row);
  170. return $this->view->fetch();
  171. }
  172. $params = $this->request->post('row/a');
  173. if (empty($params)) {
  174. $this->error(__('Parameter %s can not be empty', ''));
  175. }
  176. $params = $this->preExcludeFields($params);
  177. if (isset($params["fixed_profit_rate"])) {
  178. if ($params["fixed_profit_rate"] < 0 || $params["fixed_profit_rate"] > 90)
  179. $this->error("固定分润比例必须在0~90之间");
  180. }
  181. if (isset($params["area_id"]) && $params["area_id"] > 0) {
  182. if (is_null($row['lng']) && is_null($row["lat"])) {
  183. $area = (new Area())->where([
  184. "id" => $params["area_id"],
  185. "use" => 1,
  186. "level" => 2,
  187. ])->find();
  188. if (!$area)
  189. $this->error("地区选择不正确");
  190. $params["city_code"] = $area["area_code"];
  191. $params["lng"] = $area["lng"];
  192. $params["lat"] = $area["lat"];
  193. }
  194. } else {
  195. $this->error("地区选择不正确");
  196. }
  197. if (strlen($params["password"]) == 0)
  198. unset($params["password"]);
  199. else
  200. $params["password"] = md5($params["password"]);
  201. if (isset($params["status"]) && $params["status"] != \E_MASSAGER_STATUS::Normal) {
  202. (new MassagerActionService())->workClockIn($row->id, true);
  203. }
  204. $result = false;
  205. Db::startTrans();
  206. try {
  207. //是否采用模型验证
  208. if ($this->modelValidate) {
  209. $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
  210. $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
  211. $row->validateFailException()->validate($validate);
  212. }
  213. $result = $row->allowField(true)->save($params);
  214. Db::commit();
  215. } catch (ValidateException | PDOException | Exception $e) {
  216. Db::rollback();
  217. $this->error($e->getMessage());
  218. }
  219. if (false === $result) {
  220. $this->error(__('No rows were updated'));
  221. }
  222. $this->success();
  223. }
  224. public function check($id = null, $check = null)
  225. {
  226. if (!$id || !$check)
  227. $this->error("参数错误!");
  228. $massager = $this->model->where([
  229. "id" => $id,
  230. "status" => \E_MASSAGER_STATUS::Checking,
  231. ])->find();
  232. if (!$massager)
  233. $this->error("申请记录不存在!");
  234. $is_pass = $check === "pass";
  235. $this->model->update([
  236. "updatetime" => time(),
  237. "status" => $is_pass ? \E_MASSAGER_STATUS::Normal : \E_MASSAGER_STATUS::Hidden
  238. ], ["id" => $id]);
  239. Message::sendSystemMessage(
  240. \E_IDENTITY_TYPE::Massager,
  241. ["to_massager_id" => $id],
  242. "助教审核",
  243. "您的申请已被管理员" . ($is_pass ? "通过!" : "拒绝!")
  244. );
  245. $switch = false;//config("site.invite_grant_switch");
  246. if ($switch && $is_pass && $massager["parent_id"] > 0) {
  247. $mWalletModel = new Wallet();
  248. $parent = $this->model->get($massager["parent_id"]);
  249. if ($parent) {
  250. $parent_wallet = $mWalletModel->getWallet($parent->id);
  251. $mobile_check_pass = config("site.mobile_check_pass");
  252. (new \app\admin\model\massager\Bill())->save([
  253. "massager_id" => $parent->id,
  254. "currency_type" => \E_USER_BILL_CURRENCY_TYPE::Money,
  255. "change_type" => \E_M_BILL_CHANGE_TYPE::ChannelIncome,
  256. "change" => $mobile_check_pass,
  257. "before" => $parent_wallet["profit_amount"],
  258. "after" => $parent_wallet["profit_amount"] + $mobile_check_pass,
  259. "reason" => "电话审核通过发放奖励",
  260. "relation_no" => null,
  261. "createtime" => time()
  262. ]);
  263. if ($parent_wallet) {
  264. $mWalletModel->where("id", $parent_wallet->id)->setInc("profit_amount", $mobile_check_pass);
  265. }
  266. }
  267. }
  268. $valid = TencentCloudService::tencent_cloud_sms_send(TencentCloudService::$MASSAGE_APPLY, $massager["mobile"], [$is_pass ? "通过!" : "拒绝!"]);
  269. if ($valid->code()) {
  270. $this->success("审核成功!");
  271. }
  272. $this->error($valid->msg());
  273. }
  274. public function real_name_auth($id = null, $check = null)
  275. {
  276. if (!$id || !$check)
  277. $this->error("参数错误!");
  278. $massager = $this->model->where([
  279. "id" => $id,
  280. "status" => \E_MASSAGER_STATUS::Normal,
  281. "real_name_auth" => \E_BASE_STATUS::Default
  282. ])->find();
  283. if (!$massager)
  284. $this->error("申请记录不存在!");
  285. $is_pass = $check === "pass";
  286. $this->model->update([
  287. "updatetime" => time(),
  288. "real_name_auth" => $is_pass ? "pass" : "reject"
  289. ], ["id" => $id]);
  290. Message::sendSystemMessage(
  291. \E_IDENTITY_TYPE::Massager,
  292. ["to_massager_id" => $id],
  293. "线下面试",
  294. "您的线下面试已被管理员" . ($is_pass ? "通过!" : "拒绝!")
  295. );
  296. $switch = false;//config("site.invite_grant_switch");
  297. if ($switch && $is_pass && $massager["parent_id"] > 0) {
  298. $mWalletModel = new Wallet();
  299. $parent = $this->model->get($massager["parent_id"]);
  300. if ($parent) {
  301. $parent_wallet = $mWalletModel->getWallet($parent->id);
  302. $real_name_check_pass = config("site.real_name_check_pass");
  303. (new \app\admin\model\massager\Bill())->save([
  304. "massager_id" => $parent->id,
  305. "currency_type" => \E_USER_BILL_CURRENCY_TYPE::Money,
  306. "change_type" => \E_M_BILL_CHANGE_TYPE::ChannelIncome,
  307. "change" => $real_name_check_pass,
  308. "before" => $parent_wallet["profit_amount"],
  309. "after" => $parent_wallet["profit_amount"] + $real_name_check_pass,
  310. "reason" => "线下面试通过发放奖励",
  311. "relation_no" => null,
  312. "createtime" => time()
  313. ]);
  314. if ($parent_wallet) {
  315. $mWalletModel->where("id", $parent_wallet->id)->setInc("profit_amount", $real_name_check_pass);
  316. }
  317. }
  318. }
  319. $this->success("审核成功!");
  320. // $valid = TencentCloudService::tencent_cloud_sms_send(TencentCloudService::$MASSAGE_APPLY, $massager["mobile"], [$is_pass ? "通过!" : "拒绝!"]);
  321. // if ($valid->code()) {
  322. // $this->success("审核成功!");
  323. // }
  324. // $this->error($valid->msg());
  325. }
  326. public function wallet($id = null)
  327. {
  328. if (!$id)
  329. $this->error("ID 为空!");
  330. $m = $this->model->get($id);
  331. if (!$m)
  332. $this->error("助教不存在!");
  333. $wallet = (new \app\api\model\massager\Wallet())->getWallet($id);
  334. $bill = (new \app\api\model\massager\Bill())->where("massager_id", $id)->limit(0, 100)->order("id", "desc")->select();
  335. $this->assign("wallet", $wallet);
  336. $this->assign("rows", $bill);
  337. return $this->view->fetch();
  338. }
  339. public function duration($ids = null, $page = 1)
  340. {
  341. $params = $this->request->param();
  342. $starttime = strtotime(date("Y-m-01 00:00:00"));
  343. $endtime = strtotime(date("Y-m-d 23:59:59"));
  344. if (isset($params["startdate"])) {
  345. $s_strtotime = strtotime($params["startdate"]);
  346. if ($s_strtotime > 0)
  347. $starttime = $s_strtotime;
  348. }
  349. if (isset($params["enddate"])) {
  350. $e_strtotime = strtotime($params["enddate"]);
  351. if ($e_strtotime > 0)
  352. $endtime = strtotime(date("Y-m-d 23:59:59", $e_strtotime));
  353. }
  354. $sumDuration = (new \app\admin\model\massager\Work())
  355. ->where("massager_id", $ids)
  356. ->where("clock_in_time", ">=", $starttime)
  357. ->where("clock_off_time", "<=", $endtime)
  358. ->sum("duration");
  359. $paginate = (new \app\admin\model\massager\Work())
  360. ->where("massager_id", $ids)
  361. ->where("clock_in_time", ">=", $starttime)
  362. ->where("clock_off_time", "<=", $endtime)
  363. ->order("createtime", "desc")
  364. ->page($page)
  365. ->paginate(
  366. 10,
  367. false,
  368. [
  369. "query" => [
  370. "startdate" => isset($params["startdate"]) ? $params["startdate"] : null,
  371. "enddate" => isset($params["enddate"]) ? $params["enddate"] : null,
  372. ]
  373. ]);
  374. $this->view->assign([
  375. "paginate" => $paginate,
  376. "startdate" => date("Y-m-d", $starttime),
  377. "enddate" => date("Y-m-d", $endtime),
  378. "sumDuration" => fixed2Float($sumDuration),
  379. ]);
  380. return $this->view->fetch();
  381. }
  382. public function interiorScore($ids = null)
  383. {
  384. $params = $this->request->param();
  385. $year = isset($params["year"]) ? $params["year"] : date("Y");
  386. $month = isset($params["month"]) ? $params["month"] : date("m");
  387. $interiorScoreDetails = (new MassagerService())->updateInteriorScore($ids, $year, $month);
  388. $this->view->assign([
  389. "year" => $year,
  390. "month" => $month,
  391. "interiorScoreDetails" => $interiorScoreDetails,
  392. ]);
  393. return $this->view->fetch();
  394. }
  395. public function chatlist($ids = null)
  396. {
  397. $res = \db("fastchat_session")
  398. ->where(
  399. "((user_id = '{$ids}||massager') OR (session_type = 6 AND session_user_id = {$ids}))"
  400. )->order("id", "desc")
  401. ->limit(100)
  402. ->select();
  403. $result = [];
  404. foreach ($res as $item) {
  405. $user_id = null;
  406. if ($item["user_id"] == "{$ids}||massager") {
  407. $user_id = $item["session_user_id"];
  408. } else {
  409. $user_id = explode("||", $item["user_id"])[0];
  410. }
  411. $user = \db("user")->where("id", $user_id)->find();
  412. if ($user) {
  413. array_push($result, [
  414. "id" => $item["id"],
  415. "user" => $user,
  416. "massager_id" => $ids,
  417. "createtime" => $item["createtime"]
  418. ]);
  419. }
  420. }
  421. $this->view->assign("rows", $result);
  422. return $this->view->fetch();
  423. }
  424. public function chatrecord()
  425. {
  426. $params = $this->request->param();
  427. $start = strtotime('-7 days');
  428. $end = time();
  429. $records = \db("fastchat_record")
  430. ->where("session_id", $params["session_id"])
  431. ->whereBetween('createtime', [$start, $end])
  432. ->order("createtime", "ASC")
  433. ->select();
  434. foreach ($records as &$record) {
  435. $record["class"] = strpos($record['sender'], "massager") ? "me" : "you";
  436. }
  437. $this->view->assign("rows", $records);
  438. return $this->view->fetch();
  439. }
  440. }