WorkerForm.php 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\models\worker;
  8. use app\models\District;
  9. use app\models\SaasUser;
  10. use app\models\Order;
  11. use app\models\Cash;
  12. use app\models\User;
  13. use app\models\Worker;
  14. use app\models\WorkerCatExt;
  15. use app\models\WorkerOrderExt;
  16. use app\models\WorkerCat;
  17. use app\models\WorkerLevel;
  18. use app\models\WorkerPic;
  19. use app\models\WorkerSetting;
  20. use app\models\OrderComment;
  21. use app\models\OrderDetail;
  22. use app\utils\Notice\NoticeSend;
  23. use app\modules\client\models\v1\LoginForm;
  24. use app\models\UserShareMoney;
  25. use app\modules\client\models\OrderComplete;
  26. class WorkerForm extends Model
  27. {
  28. public $store_id;
  29. public $verify_code;
  30. public $id;
  31. public $name; //名称
  32. public $gender;
  33. public $age;
  34. public $form;
  35. public $type;
  36. public $cat_id;
  37. public $user;
  38. public $user_id;
  39. public $worker_id;
  40. public $level;
  41. public $desc;
  42. public $tel;
  43. public $logo;
  44. public $status;
  45. public $open_status;
  46. public $reason;
  47. public $area;
  48. public $lat;
  49. public $lng;
  50. public $province_id;
  51. public $city_id;
  52. public $district_id;
  53. public $address;
  54. public $nickname;
  55. public $order_id;
  56. public $goods_name;
  57. public $score;
  58. public $order_range;
  59. public $begin;
  60. public $end;
  61. public $key_word;
  62. public $is_hide;
  63. public $setting;
  64. public $pic_url;
  65. public function rules()
  66. {
  67. return [
  68. [['id', 'user_id', 'level', 'type', 'status', 'province_id', 'city_id', 'district_id', 'open_status', 'gender', 'age'], 'integer'],
  69. [['desc', 'name', 'tel', 'logo', 'reason', 'area', 'lat', 'lng', 'address', 'nickname', 'verify_code', 'cat_id'], 'string'],
  70. [['user', 'form', 'order_id', 'worker_id', 'goods_name', 'score', 'begin', 'end', 'key_word', 'gender', 'is_hide', 'setting', 'pic_url', 'order_range'], 'safe'],
  71. ];
  72. }
  73. public function workerList() {
  74. try {
  75. $store_id = $this->store_id;
  76. $status = $this->status;
  77. $open_status = $this->open_status;
  78. $name = $this->name;
  79. $cat_id = $this->cat_id;
  80. $level = $this->level;
  81. $nickname = $this->nickname;
  82. $tel = $this->tel;
  83. $query = Worker::find()->alias('w')->where(['w.store_id' => $store_id, 'w.status' => [Worker::STATUS_WAIT_AUDIT, Worker::STATUS_VALID, Worker::STATUS_REJECT]]);
  84. if (!is_null($status) && in_array($status, [Worker::STATUS_WAIT_AUDIT, Worker::STATUS_VALID, Worker::STATUS_REJECT])) {
  85. $query->andWhere(['w.status' => $status]);
  86. }
  87. if (is_null($status)) {
  88. $query->andWhere(['w.status' => Worker::STATUS_VALID]);
  89. }
  90. if ($name) {
  91. $query->andWhere(['LIKE', 'w.name', $name]);
  92. }
  93. if ($tel) {
  94. $query->andWhere(['w.tel' => $tel]);
  95. }
  96. if ($cat_id) {
  97. $cat_id = explode(',', $cat_id);
  98. $worker_ = WorkerCatExt::find()->where(['cat_id' => $cat_id, 'is_delete' => 0])->select('worker_id')->column();
  99. $worker_ = array_merge($worker_, [0]);
  100. $query->andWhere(['w.id' => $worker_]);
  101. }
  102. if ($level) {
  103. $query->andWhere(['w.level' => $level]);
  104. }
  105. if ($nickname) {
  106. $query->andWhere(['LIKE', 'su.name', $nickname]);
  107. }
  108. // if (!is_null($open_status) && in_array($open_status, [1, 2, 3])) {
  109. // $query->andWhere(['w.status' => $status]);
  110. // }
  111. if (!is_null($open_status)) {
  112. if (in_array($open_status, [0, 1])) {
  113. $query->andWhere(['w.open_status' => $open_status]);
  114. if ((int)$open_status === 1) {
  115. $worker_ids = WorkerOrderExt::find()->where(['AND',
  116. ['user_revoke' => 0],
  117. ['<', 'time_outgoing', time()],
  118. ['>', 'time_end_service', time()]])->select('worker_id')->column();
  119. $worker_ids = array_merge($worker_ids, [0]);
  120. $query->andWhere(['NOT IN', 'w.id', $worker_ids]);
  121. }
  122. }
  123. if ((int)$open_status === 2) {
  124. $query->leftJoin(['o' => WorkerOrderExt::tableName()], 'o.worker_id = w.id');
  125. $query->andWhere(['AND',
  126. ['w.open_status' => 1, 'o.user_revoke' => 0],
  127. ['<', 'o.time_outgoing', time()],
  128. ['>', 'o.time_end_service', time()]
  129. ]);
  130. }
  131. }
  132. $query->leftJoin(['u' => User::tableName()], 'w.user_id = u.id')
  133. ->leftJoin(['su' => SaasUser::tableName()], 'w.saas_user_id = su.id')
  134. ->select('w.*, su.name nickname')
  135. ->orderBy('w.created_at desc');
  136. $list = pagination_make($query);
  137. foreach ($list['list'] as &$item) {
  138. $item['form'] = json_decode($item['form'], true);
  139. $item['status'] = (int)$item['status'];
  140. $item['open_status'] = (int)$item['open_status'];
  141. if ($item['book_end_time'] <= 0 && $item['book_start_time'] <= 0) {
  142. $item['worker_time'] = '未设置服务时间';
  143. }
  144. if ($item['book_start_time'] > 0) {
  145. if (strlen($item['book_start_time']) === 3) {
  146. $item['book_start_time'] = '0' . $item['book_start_time'];
  147. }
  148. $hour = substr($item['book_start_time'], 0, 2);
  149. $minute = substr($item['book_start_time'], -2);
  150. $item['worker_time'] = $hour . ':' . $minute;
  151. } else {
  152. $item['worker_time'] = "00:00";
  153. }
  154. if ($item['book_end_time'] > 0) {
  155. if (strlen($item['book_end_time']) === 3) {
  156. $item['book_end_time'] = '0' . $item['book_end_time'];
  157. }
  158. $hour = substr($item['book_end_time'], 0, 2);
  159. $minute = substr($item['book_end_time'], -2);
  160. $item['worker_time'] .= '-'. $hour . ':' . $minute;
  161. } else {
  162. $item['worker_time'] .= "-00:00";
  163. }
  164. if ($item['open_status'] === 1) {
  165. $order_ext = WorkerOrderExt::find()->where(['AND',
  166. ['user_revoke' => 0, 'worker_id' => $item['id']],
  167. ['<=', 'time_start_service', time()],
  168. ['>=', 'time_end_service', time()]
  169. ])->one();
  170. if ($order_ext) {
  171. $item['open_status'] = 2;
  172. }
  173. if ($item['open_status'] === 1) {
  174. if ($item['book_end_time'] < date("Hi")) {
  175. $item['open_status'] = 0;
  176. }
  177. }
  178. }
  179. //订单数量
  180. $order_ext = WorkerOrderExt::find()->where(['worker_id' => $item['id']])->select('order_id')->asArray()->all();
  181. $item['order_num'] = (int)count($order_ext);
  182. $item['province'] = District::find()->where(['id' => $item['province_id']])->select('name')->scalar();
  183. $item['city'] = District::find()->where(['id' => $item['city_id']])->select('name')->scalar();
  184. $item['district'] = District::find()->where(['id' => $item['district_id']])->select('name')->scalar();
  185. // $item['address'] = $area['address'];
  186. $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
  187. $item['updated_at'] = date('Y-m-d H:i:s', $item['updated_at']);
  188. $item['pic_url'] = WorkerPic::find()->where(['worker_id' => $item['id'], 'is_delete' => 0])->select('pic_url')->asArray()->all();
  189. if ($item['pic_url']) {
  190. foreach ($item['pic_url'] as &$value) {
  191. if (strpos($value['pic_url'], 'https:') === false && strpos($value['pic_url'], 'http:') === false) {
  192. $value['pic_url'] = 'https:' . $value['pic_url'];
  193. }
  194. }
  195. }
  196. $item['cat_id'] = WorkerCatExt::find()->where(['worker_id' => $item['id'], 'is_delete' => 0])->select('cat_id')->column();
  197. $item['cat_name'] = WorkerCat::find()->where(['id' => $item['cat_id']])->select('name')->column();
  198. }
  199. $worker_level = WorkerLevel::find()->where(['status' => 1, 'store_id' => $store_id, 'is_delete' => 0])->select('level id, name')
  200. ->asArray()->all();
  201. $worker_cat = WorkerCat::find()->where(['is_show' => 1, 'store_id' => $store_id, 'is_delete' => 0])->select('id, name')->orderBy('sort desc')
  202. ->asArray()->all();
  203. return [
  204. 'code' => 0,
  205. 'msg' => 'success',
  206. 'data' => [
  207. 'data' => $list['list'],
  208. 'worker_level' => $worker_level,
  209. 'worker_cat' => $worker_cat,
  210. 'pageNo' => $list['pageNo'],
  211. 'totalCount' => $list['totalCount'],
  212. ],
  213. ];
  214. } catch (\Exception $e) {
  215. return [
  216. 'code' => 1,
  217. 'msg' => $e->getMessage()
  218. ];
  219. }
  220. }
  221. public function workerSave() {
  222. $t = \Yii::$app->db->beginTransaction();
  223. try {
  224. $id = $this->id;
  225. $name = $this->name;
  226. $cat_id = $this->cat_id;
  227. $user_id = $this->user_id;
  228. $level = $this->level;
  229. $desc = $this->desc;
  230. $tel = $this->tel;
  231. $logo = $this->logo;
  232. $lat = $this->lat;
  233. $lng = $this->lng;
  234. $province_id = $this->province_id;
  235. $city_id = $this->city_id;
  236. $district_id = $this->district_id;
  237. $pic_url = $this->pic_url;
  238. $store_id = $this->store_id;
  239. //查询用户信息
  240. $user = User::findOne(['store_id' => $store_id, 'id' => $user_id, 'is_delete' => 0]);
  241. if (!$user || !$user->binding) {
  242. throw new \Exception('商城用户信息查询失败');
  243. }
  244. $saas_user = SaasUser::findOne(['mobile' => $user->binding]);
  245. if (!$saas_user) {
  246. throw new \Exception('用户信息查询失败');
  247. }
  248. //查询分类信息
  249. $work_cat = WorkerCat::findOne(['id' => $cat_id, 'store_id' => $store_id, 'is_show' => 1]);
  250. if (!$work_cat) {
  251. throw new \Exception('分类信息查询失败');
  252. }
  253. //查询等级信息
  254. if ($level) {
  255. $worker_level = WorkerLevel::findOne(['level' => $level, 'status' => 1, 'store_id' => $store_id]);
  256. if (!$worker_level) {
  257. throw new \Exception('服务人员等级查询失败');
  258. }
  259. } else {
  260. $worker_level = WorkerLevel::find()->where(['status' => 1, 'store_id' => $store_id])
  261. ->orderBy('id ASC')->select('level')->asArray()->one();
  262. if (!$worker_level) {
  263. throw new \Exception('服务人员等级查询失败');
  264. }
  265. $level = $worker_level['level'];
  266. }
  267. if ($province_id && $city_id && $district_id) {
  268. //地址信息
  269. $province = District::find()->where(['id' => $province_id])->select('name')->scalar();
  270. $city = District::find()->where(['id' => $city_id])->select('name')->scalar();
  271. $district = District::find()->where(['id' => $district_id])->select('name')->scalar();
  272. if (!$province || !$city || !$district) {
  273. throw new \Exception('省市区查询失败');
  274. }
  275. }
  276. $worker = Worker::findOne(['id' => $id, 'store_id' => $store_id]);
  277. if (!$worker) {
  278. $worker = new Worker();
  279. $worker->store_id = $store_id;
  280. $worker->form = '';
  281. }
  282. $worker->status = 1;
  283. $worker->name = $name;
  284. // $worker->cat_id = $cat_id;
  285. $worker->user_id = $user->id;
  286. $worker->saas_user_id = $saas_user->id;
  287. $worker->level = $level;
  288. $worker->name = $name;
  289. // $worker->desc = $desc ?? '';
  290. // $worker->tel = $tel ?? $saas_user->mobile;
  291. // $worker->logo = $logo ?? $saas_user->avatar;
  292. // $worker->area = '';//$area;
  293. // $worker->lat = $lat ?? '0.00';
  294. // $worker->lng = $lng ?? '0.00';
  295. // $worker->province_id = $province_id ?? 0;
  296. // $worker->city_id = $city_id ?? 0;
  297. // $worker->district_id = $district_id ?? 0;
  298. if (!$worker->save()) {
  299. throw new \Exception(implode(';', array_values($worker->firstErrors)));
  300. }
  301. WorkerCatExt::deleteAll(['worker_id' => $worker->id]);
  302. $cat_id = explode(',', $cat_id);
  303. foreach ($cat_id as $cat_id_) {
  304. $worker_cat = WorkerCat::findOne(['id' => $cat_id_, 'is_delete' => 0, 'is_show' => 1]);
  305. if ($worker_cat) {
  306. $worker_cat_ext = new WorkerCatExt();
  307. $worker_cat_ext->cat_id = $cat_id_;
  308. $worker_cat_ext->worker_id = $worker->id;
  309. $worker_cat_ext->store_id = $store_id;
  310. $worker_cat_ext->save();
  311. }
  312. }
  313. if (!is_null($pic_url)) {
  314. WorkerPic::updateAll(['is_delete' => 1], ['worker_id' => $worker->id, 'is_delete' => 0]);
  315. $pic_url = json_decode($pic_url, true);
  316. foreach ($pic_url as $item) {
  317. $pic = new WorkerPic();
  318. $pic->worker_id = $worker->id;
  319. $pic->pic_url = $item['pic_url'];
  320. if (!$pic->save()) {
  321. throw new \Exception(json_encode($pic->errors));
  322. }
  323. }
  324. }
  325. $t->commit();
  326. return [
  327. 'code' => 0,
  328. 'msg' => '操作成功'
  329. ];
  330. } catch (\Exception $e) {
  331. $t->rollBack();
  332. return [
  333. 'code' => 1,
  334. 'msg' => $e->getMessage()
  335. ];
  336. }
  337. }
  338. public function workerStatus() {
  339. $t = \Yii::$app->db->beginTransaction();
  340. try {
  341. $id = $this->id;
  342. $status = (int)$this->status;
  343. $reason = $this->reason;
  344. $store_id = $this->store_id;
  345. $worker = Worker::findOne(['id' => $id, 'store_id' => $store_id]);
  346. if (!$worker) {
  347. throw new \Exception('查询信息失败');
  348. }
  349. if (!in_array($status, [Worker::STATUS_VALID, Worker::STATUS_REJECT, Worker::STATUS_CLOSE])) {
  350. throw new \Exception('状态参数错误');
  351. }
  352. if ((int)$worker->status !== Worker::STATUS_WAIT_AUDIT && in_array($status, [Worker::STATUS_VALID, Worker::STATUS_REJECT])) {
  353. throw new \Exception('已审核完成,请勿重复操作');
  354. }
  355. // if ((int)$worker->status !== Worker::STATUS_WAIT_AUDIT && $status === Worker::STATUS_REJECT) {
  356. // throw new \Exception('数据状态错误');
  357. // }
  358. if (in_array($status, [Worker::STATUS_VALID, Worker::STATUS_REJECT])) {
  359. if ($status === Worker::STATUS_REJECT) {
  360. if (!$reason) {
  361. throw new \Exception('请填写原因');
  362. } else {
  363. $worker->reason = $reason;
  364. }
  365. }
  366. }
  367. $worker->status = $status;
  368. if ($status == Worker::STATUS_CLOSE) {
  369. WorkerCatExt::deleteAll(['worker_id' => $worker->id]);
  370. }
  371. if (!$worker->save()) {
  372. throw new \Exception(json_encode($worker->errors));
  373. }
  374. $t->commit();
  375. if (in_array($status, [Worker::STATUS_VALID, Worker::STATUS_REJECT])) {
  376. $res = NoticeSend::AgentExamine($worker->id, 3);
  377. if (isset($res['code']) && $res['code'] !== 0) {
  378. debug_log($res, 'sms.log');
  379. }
  380. }
  381. return [
  382. 'code' => 0,
  383. 'msg' => '操作成功'
  384. ];
  385. } catch (\Exception $e) {
  386. $t->rollBack();
  387. return [
  388. 'code' => 1,
  389. 'msg' => $e->getMessage()
  390. ];
  391. }
  392. }
  393. public function reg() {
  394. try {
  395. $form = new LoginForm();
  396. $form->store_id = $this->store_id;
  397. $form->phone = $this->tel;
  398. $form->verify_code = $this->verify_code;
  399. $verifySmsCode = $form->verifySmsCode(LoginForm::CACHE_KEY_BIND_PHONE);
  400. if ($verifySmsCode['code'] != 0) {
  401. return $verifySmsCode;
  402. }
  403. $saas_user = SaasUser::findOne(['mobile' => $this->user->binding]);
  404. if (!$saas_user) {
  405. throw new \Exception('用户信息查询失败');
  406. }
  407. $worker = Worker::findOne(['user_id' => $this->user->id, 'status' => Worker::STATUS_VALID]);
  408. if ($worker) {
  409. if($worker->status != Worker::STATUS_REJECT){
  410. throw new \Exception('状态异常');
  411. }
  412. }else{
  413. $worker = new Worker();
  414. $worker->store_id = $this->store_id;
  415. }
  416. $worker->cat_id = $this->cat_id;
  417. $worker->name = $this->name;
  418. $worker->user_id = $this->user->id;
  419. $worker->saas_user_id = $saas_user->id;
  420. $worker->tel = $this->tel;
  421. $worker->logo = $this->logo;
  422. $worker->gender = $this->gender;
  423. $worker->age = $this->age;
  424. $worker->logo = $this->logo;
  425. $worker->province_id = $this->province_id ?? 0;
  426. $worker->city_id = $this->city_id ?? 0;
  427. $worker->district_id = $this->district_id ?? 0;
  428. $worker->form = is_string($this->form) ? $this->form : json_encode($this->form);
  429. $worker->lat = $this->lat;
  430. $worker->lng = $this->lng;
  431. $worker->status = 0;
  432. if (!$worker->save()) {
  433. throw new \Exception('保存失败' . array_shift($worker->getFirstErrors()));
  434. }
  435. return [
  436. 'code' => 0,
  437. 'msg' => '申请成功,请等待审核'
  438. ];
  439. } catch (\Exception $e) {
  440. return [
  441. 'code' => 1,
  442. 'msg' => '保存失败' . $e->getMessage()
  443. ];
  444. }
  445. }
  446. //分配订单-服务人员列表
  447. public function canBindWorkerList()
  448. {
  449. $store_id = $this->store_id;
  450. $order_id = $this->order_id;
  451. $type = $this->type;
  452. $setting = WorkerSetting::getByStoreId($store_id);
  453. $orderSpace = $setting['order_space'];
  454. $WorkerOrderExt = WorkerOrderExt::findOne(['store_id' => $store_id, 'order_id' => $order_id, 'status_ext' => WorkerOrderExt::STATUS_EXT_WAIT_BIND]);
  455. if(empty($WorkerOrderExt)){
  456. return [
  457. 'code' => 1,
  458. 'msg' => '参数错误,订单ext不存在',
  459. ];
  460. }
  461. $order = Order::findOne($order_id);
  462. $gnum = count($order->detail);
  463. $sql = '
  464. SELECT
  465. w.id
  466. FROM
  467. cyy_worker w
  468. LEFT JOIN (
  469. SELECT
  470. count(id) num,
  471. worker_id
  472. FROM
  473. cyy_worker_goods
  474. WHERE
  475. goods_id IN (
  476. SELECT goods_id FROM cyy_order_detail WHERE order_id = :order_id AND is_delete=0
  477. )
  478. GROUP BY
  479. worker_id
  480. ) wg ON w.id = wg.worker_id
  481. WHERE
  482. wg.num = :gnum AND w.status != :status';
  483. $queryWorkerId = \Yii::$app->db->createCommand($sql, [':order_id' => $order_id, ':gnum' => $gnum, ':status' => Worker::STATUS_VALID])->getRawSql();
  484. $queryOrder = Worker::find()->alias('w')->leftJoin([
  485. 'woe' => WorkerOrderExt::find()->where([
  486. 'and',
  487. ['>=', 'status_ext', WorkerOrderExt::STATUS_EXT_HAS_BIND],
  488. ['<', 'status_ext', WorkerOrderExt::STATUS_EXT_CANCEL],
  489. ])->select('id doing, worker_id')
  490. ], 'w.id = woe.worker_id')->where([
  491. 'w.store_id' => $store_id,
  492. 'w.status' => Worker::STATUS_VALID,
  493. ]);
  494. if($this->name){
  495. $queryOrder->andWhere(['like', 'w.name', $this->name]);
  496. }
  497. if($this->tel){
  498. $queryOrder->andWhere(['like', 'w.tel', $this->tel]);
  499. }
  500. if($type == 1){
  501. $queryOrder->andWhere(['woe.doing' => null]);
  502. }
  503. if($type == 2){
  504. $queryOrder->andWhere(['>', 'woe.doing', 0]);
  505. }
  506. if($type == 3){
  507. $queryOrder->andWhere(['w.open_status' => 0]);
  508. }
  509. $queryOrder->andWhere('w.id in ('. $queryWorkerId .')');
  510. $queryDis = 'ROUND(st_distance_sphere(point('. $WorkerOrderExt->lng .', '. $WorkerOrderExt->lat .'), point(w.lng, w.lat)), 2)';
  511. $queryOrder->andWhere($queryDis . " < :dis", [':dis' => $orderSpace]);
  512. $queryOrder->select('*');
  513. $queryOrder->addSelect([$queryDis . ' dis']);
  514. $queryOrder->orderBy('dis ASC, doing ASC');
  515. $data = pagination_make($queryOrder);
  516. foreach($data['list'] as &$item){
  517. $item['ignore'] = 0;
  518. $cacheV = WorkerOrderExt::cacheIgnoreOrderId($item->id);
  519. if($cacheV && in_array($order_id, array_keys($cacheV))){
  520. $item['ignore'] = 1;
  521. }
  522. $item['canBind'] = 1;
  523. if(empty($item['doing'])){
  524. $item['canBind'] = 1;
  525. }
  526. if($item['doing']){
  527. $item['canBind'] = 2;
  528. }
  529. if(empty($item['open_status'])){
  530. $item['canBind'] = 3;
  531. }
  532. }
  533. $res = [
  534. 'code' => 0,
  535. 'msg' => 'success',
  536. 'data' => $data,
  537. 'q' => $queryOrder->createCommand()->getRawSql(),
  538. ];
  539. return $res;
  540. }
  541. //分配订单
  542. public function bindWorker()
  543. {
  544. $store_id = $this->store_id;
  545. $order_id = $this->order_id;
  546. $worker_id = $this->worker_id;
  547. if(empty($order_id) || empty($worker_id)){
  548. return [
  549. 'code' => 1,
  550. 'msg' => '参数错误1',
  551. '$order_id' => $order_id,
  552. '$worker_id' => $worker_id,
  553. ];
  554. }
  555. $orderExt = WorkerOrderExt::findOne(['store_id' => $store_id, 'order_id' => $order_id, 'status_ext' => WorkerOrderExt::STATUS_EXT_WAIT_BIND]);
  556. if(empty($orderExt)){
  557. return [
  558. 'code' => 1,
  559. 'msg' => '参数错误,订单ext不存在',
  560. ];
  561. }
  562. $t = \Yii::$app->db->beginTransaction();
  563. try{
  564. $orderExt = WorkerOrderExt::find()->where('id = :id FOR UPDATE', [':id' => $orderExt->id])->one();
  565. if(!$orderExt){
  566. throw new \Exception('锁失败');
  567. }
  568. $orderExt->worker_id = $worker_id;
  569. $orderExt->status_ext = WorkerOrderExt::STATUS_EXT_WAIT_BIND_OK;
  570. $save = $orderExt->save();
  571. if(!$save){
  572. throw new \Exception(array_shift($orderExt->getFirstErrors()));
  573. }
  574. $t->commit();
  575. $order = Order::findOne($order_id);
  576. NoticeSend::PlaceOrder($order->order_no, $order->md_id, $order->store_id, $order);
  577. return [
  578. 'code' => 0,
  579. 'msg' => 'success',
  580. ];
  581. } catch (\Exception $ex) {
  582. $t->rollBack();
  583. return [
  584. 'code' => 1,
  585. 'msg' => '操作失败,' . $ex->getMessage(),
  586. ];
  587. }
  588. }
  589. //确认收款
  590. public function orderIsPay()
  591. {
  592. $store_id = $this->store_id;
  593. $order_id = $this->order_id;
  594. if(empty($order_id)){
  595. return [
  596. 'code' => 1,
  597. 'msg' => '参数错误1',
  598. '$order_id' => $order_id,
  599. ];
  600. }
  601. $order = Order::findOne(['id' => $order_id, 'store_id' => $store_id, 'trade_status' => Order::ORDER_FLOW_DEFAULT]);
  602. if(empty($order)){
  603. return [
  604. 'code' => 1,
  605. 'msg' => '参数错误,订单不存在或状态异常',
  606. ];
  607. }
  608. $t = \Yii::$app->db->beginTransaction();
  609. try{
  610. $order = Order::find()->where('id = :id FOR UPDATE', [':id' => $order_id])->one();
  611. if(!$order){
  612. throw new \Exception('锁失败');
  613. }
  614. $order->is_pay = 1;
  615. $order->pay_type = 3;
  616. $order->pay_time = time();
  617. $order->trade_status = Order::ORDER_FLOW_NO_SEND;
  618. $save = $order->save();
  619. if(!$save){
  620. throw new \Exception(array_shift($order->getFirstErrors()));
  621. }
  622. // 支付完成后,相关操作
  623. $form = new OrderComplete();
  624. $form->order_id = $order->id;
  625. $form->order_type = 0;
  626. $form->store_id = $store_id;
  627. $form->notify();
  628. $t->commit();
  629. return [
  630. 'code' => 0,
  631. 'msg' => '操作成功',
  632. ];
  633. } catch (\Exception $ex) {
  634. $t->rollBack();
  635. return [
  636. 'code' => 1,
  637. 'msg' => '操作失败,' . $ex->getMessage(),
  638. ];
  639. }
  640. }
  641. //确认收货
  642. public function orderConfirm()
  643. {
  644. $store_id = $this->store_id;
  645. $order_id = $this->order_id;
  646. if(empty($order_id)){
  647. return [
  648. 'code' => 1,
  649. 'msg' => '参数错误1',
  650. '$order_id' => $order_id,
  651. ];
  652. }
  653. $order = Order::findOne(['id' => $order_id, 'store_id' => $store_id, 'is_pay' => 1]);
  654. if(empty($order)){
  655. return [
  656. 'code' => 1,
  657. 'msg' => '参数错误,订单不存在或订单未付款',
  658. ];
  659. }
  660. $t = \Yii::$app->db->beginTransaction();
  661. try{
  662. $order = Order::find()->where('id = :id FOR UPDATE', [':id' => $order_id])->one();
  663. if(!$order){
  664. throw new \Exception('锁失败');
  665. }
  666. $order->trade_status = Order::ORDER_FLOW_CONFIRM;
  667. $order->confirm_time = time();
  668. $save = $order->save();
  669. if(!$save){
  670. throw new \Exception(array_shift($order->getFirstErrors()));
  671. }
  672. $t->commit();
  673. return [
  674. 'code' => 0,
  675. 'msg' => '操作成功',
  676. ];
  677. } catch (\Exception $ex) {
  678. $t->rollBack();
  679. return [
  680. 'code' => 1,
  681. 'msg' => '操作失败,' . $ex->getMessage(),
  682. ];
  683. }
  684. }
  685. public function commentList() {
  686. $store_id = $this->store_id;
  687. $queryOrder = WorkerOrderExt::find()->where(['store_id' => $store_id])->select('order_id');
  688. $query = OrderComment::find()->alias('oc')->leftJoin([
  689. 'woe' => WorkerOrderExt::tableName()
  690. ], 'oc.order_id = woe.order_id')->leftJoin([
  691. 'w' => Worker::tableName()
  692. ], 'w.id = woe.worker_id')->leftJoin([
  693. 'o' => Order::tableName()
  694. ], 'oc.order_id = o.id')->leftJoin([
  695. 'od' => OrderDetail::tableName()
  696. ], 'oc.order_detail_id = od.id')->leftJoin([
  697. 'u' => User::tableName()
  698. ], 'oc.user_id = u.id')->leftJoin([
  699. 'su' => SaasUser::tableName()
  700. ], 'su.mobile = u.binding')->where([
  701. 'oc.order_id' => $queryOrder,
  702. 'oc.is_delete' => OrderComment::IS_DELETE_FALSE,
  703. ])->groupBy('oc.id');
  704. if(isset($this->is_hide) && $this->is_hide >= 0){
  705. $query->andWhere(['oc.is_hide' => $this->is_hide]);
  706. }
  707. if($this->goods_name){
  708. $query->andWhere(['like', 'od.goods_name', $this->goods_name]);
  709. }
  710. if($this->nickname){
  711. $query->andWhere(['like', 'su.name', $this->nickname]);
  712. }
  713. if($this->key_word){
  714. $query->andWhere(['like', 'od.content', $this->key_word]);
  715. }
  716. if($this->score > 0){
  717. if($this->score == 3){
  718. $query->andWhere(['>=', 'oc.score', $this->score]);
  719. }else{
  720. $query->andWhere(['oc.score' => $this->score]);
  721. }
  722. }
  723. if($this->begin){
  724. $query->andWhere(['>=', 'oc.created_at', $this->begin]);
  725. }
  726. if($this->end){
  727. $query->andWhere(['<=', 'oc.created_at', $this->end]);
  728. }
  729. $queryOrderBy = 'oc.id DESC';
  730. if($orderby == 1){
  731. $queryOrderBy = 'oc.id DESC';
  732. }else if($orderby == 2){
  733. $queryOrderBy = 'oc.id ASC';
  734. }
  735. $query->orderBy($queryOrderBy);
  736. $query->select('oc.*, o.order_no, od.goods_name, od.pic goods_pic, su.name su_name, su.avatar su_avatar, w.name w_name, w.logo w_logo, w.tel w_tel');
  737. $data = pagination_make($query);
  738. foreach($data['list'] as &$item){
  739. $item['pic_list'] = json_decode($item['pic_list']);
  740. }
  741. $data['data'] = $data['list'];
  742. unset($data['list']);
  743. $res = [
  744. 'code' => 0,
  745. 'msg' => 'success',
  746. 'data' => $data,
  747. 'q' => $query->createCommand()->getRawSql(),
  748. ];
  749. return $res;
  750. }
  751. public function setting() {
  752. $store_id = $this->store_id;
  753. $setting = WorkerSetting::getByStoreId($store_id);
  754. if($this->setting){
  755. $post = $this->setting;
  756. if(is_string($post)){
  757. $post = json_decode($post, true);
  758. }
  759. if (!$setting) {
  760. $setting = new WorkerSetting();
  761. $setting->store_id = $this->store_id;
  762. }
  763. $setting->setAttributes($post, false);
  764. if($post['form_apply']['list']){
  765. foreach($post['form_apply']['list'] as $i => &$item){
  766. if(empty($item['id'])){
  767. $item['id'] = time() . random_int(10000, 99999);
  768. }
  769. }
  770. }
  771. $setting->form_apply = $post['form_apply'] ? json_encode($post['form_apply']) : '';
  772. $setting->tag = $post['tag'];
  773. $setting->banner = $post['banner'] ? json_encode($post['banner']) : '';
  774. if (!$setting->save()) {
  775. // throw new \Exception('保存失败' . array_shift($setting->getFirstErrors()));
  776. return [
  777. 'code' => 1,
  778. 'msg' => '保存失败' . array_shift($setting->getFirstErrors()),
  779. ];
  780. }
  781. }
  782. if($setting){
  783. $setting->form_apply = json_decode($setting->form_apply, true);
  784. $setting->banner = json_decode($setting->banner, true);
  785. }
  786. return [
  787. 'code' => 0,
  788. 'msg' => 'ok',
  789. 'setting' => $setting ?? (object)[],
  790. ];
  791. }
  792. //佣金列表
  793. public function storeWorkerProfitList() {
  794. $query = Order::find()->alias('o')->leftJoin(['oe' => WorkerOrderExt::tableName()], 'o.id = oe.order_id')->where([
  795. 'o.is_delete' => 0, 'o.store_id' => $this->store_id
  796. ])->andWhere([
  797. '<>', 'o.trade_status', Order::ORDER_FLOW_CANCEL
  798. ]);
  799. $query->orderBy('o.id DESC');
  800. $pagination = pagination_make($query);
  801. $listArray = $pagination['list'];
  802. return [
  803. 'code' => 0,
  804. 'msg' => 'success',
  805. 'data' => [
  806. 'data' => $listArray,
  807. 'pageNo' => $pagination['pageNo'],
  808. 'pageSize' => $pagination['pageSize'],
  809. 'totalCount' => $pagination['totalCount'],
  810. ],
  811. ];
  812. }
  813. //服务人员佣金列表
  814. public function workerProfitList($is_price_no = 0) {
  815. $query = Order::find()->alias('o')
  816. ->leftJoin(['oe' => WorkerOrderExt::tableName()], 'o.id = oe.order_id')
  817. ->where([
  818. 'o.is_delete' => 0, 'o.store_id' => $this->store_id
  819. ])->andWhere([
  820. '<>', 'o.trade_status', Order::ORDER_FLOW_CANCEL
  821. ])->andWhere([
  822. 'oe.worker_id' => $this->worker_id,
  823. 'o.is_pay' => 1,
  824. ]);
  825. $sumQuery = clone $query;
  826. $sum_money = $sumQuery->sum('worker_price');
  827. $sumQueryIsPriceNo = clone $query;
  828. $sumQueryIsPriceNo->andWhere(['worker_is_price' => 0]);
  829. $sumMoneyIsPriceNo = $sumQueryIsPriceNo->sum('worker_price');
  830. if($is_price_no){
  831. $query->andWhere(['worker_is_price' => 0]);
  832. }
  833. $query->select('o.order_no, o.id, o.pay_time, oe.worker_is_price_time, oe.worker_is_price, oe.worker_price');
  834. $query->orderBy('o.id DESC');
  835. $pagination = pagination_make($query);
  836. $listArray = $pagination['list'];
  837. foreach($listArray as &$item){
  838. $item['source_name'] = '服务人员佣金';
  839. $item['created_at'] = $item['pay_time'];
  840. $item['send_time'] = $item['worker_is_price_time'];
  841. $item['money'] = $item['worker_price'];
  842. $item['is_price'] = $item['worker_is_price'];
  843. }
  844. return [
  845. 'sum_money' => (float)$sum_money,
  846. 'sumMoneyIsPriceNo' => (float)$sumMoneyIsPriceNo,
  847. 'data' => $listArray,
  848. 'pageNo' => $pagination['pageNo'],
  849. 'pageSize' => $pagination['pageSize'],
  850. 'totalCount' => $pagination['totalCount'],
  851. ];
  852. }
  853. //发放佣金
  854. public static function workerProfitSend($order_id = 0) {
  855. $woe = WorkerOrderExt::findOne(['order_id' => $order_id, 'worker_is_price' => 0]);
  856. if(!$woe){
  857. return [
  858. 'code' => 1,
  859. 'msg' => '订单不存在或已发放',
  860. ];
  861. }
  862. $key = 'workerProfitSend_' . $order_id;
  863. if(cache()->get($key)){
  864. return [
  865. 'code' => 1,
  866. 'msg' => '已操作,稍后再试',
  867. ];
  868. }
  869. cache()->set($key, 1, 60);
  870. $t = \Yii::$app->db->beginTransaction();
  871. try{
  872. $woe->worker_is_price = 1;
  873. $woe->worker_is_price_time = time();
  874. $save = $woe->save();
  875. if(!$save){
  876. throw new \Exception('发放状态修改失败' . array_shift($woe->getFirstErrors()));
  877. }
  878. $worker = Worker::findOne($woe->worker_id);
  879. $user = User::findOne($worker->user_id);
  880. $profit = $woe['worker_price'];
  881. $user->total_price += $profit;
  882. $user->price += $profit;
  883. $save = $user->save();
  884. if(!$save){
  885. throw new \Exception('用户佣金信息修改失败' . array_shift($user->getFirstErrors()));
  886. }
  887. UserShareMoney::set($profit, $user->id, $woe->order_id, 0, 1, $woe->store_id, Order::ORDER_TYPE_WORKER);
  888. $t->commit();
  889. return [
  890. 'code' => 0,
  891. 'msg' => 'ok',
  892. ];
  893. } catch (\Exception $ex) {
  894. $t->rollBack();
  895. return [
  896. 'code' => 1,
  897. 'msg' => '操作失败,' . $ex->getMessage(),
  898. ];
  899. }
  900. }
  901. /**
  902. * 获取提现列表
  903. * @return array
  904. */
  905. public function getStoreWorkerCashList(){
  906. $query = Cash::find()->alias('c')
  907. ->where(['c.is_delete' => Cash::IS_DELETE_NO, 'c.store_id' => $this->store_id])
  908. ->leftJoin(['u' => User::tableName()], 'u.id=c.user_id')
  909. ->leftJoin(['w' => Worker::tableName()], 'w.user_id=c.user_id')
  910. ->andWhere([
  911. 'c.cash_type' => Cash::IS_CASH_TYPE_WORKER
  912. ]);
  913. if ($this->keyword) {
  914. $query->andWhere([
  915. 'or',
  916. ['like', 'u.nickname', $this->keyword],
  917. ['like', 'w.name', $this->keyword]
  918. ]);
  919. }
  920. if ($this->dateStart) {
  921. $query->andWhere(['>=', 'c.created_at', strtotime($this->dateStart)]);
  922. }
  923. if ($this->dateEnd) {
  924. $query->andWhere(['<=', 'c.created_at', strtotime($this->dateEnd)]);
  925. }
  926. if ($this->status == Cash::STATUS_APPLY and $this->status != '') {//待审核
  927. $query->andWhere(['c.status' => Cash::STATUS_APPLY]);
  928. }
  929. if ($this->status == Cash::STATUS_CONFIRM) {//待打款
  930. $query->andWhere(['c.status' => Cash::STATUS_CONFIRM]);
  931. }
  932. if ($this->status == Cash::STATUS_GIVEN) {//已打款
  933. $query->andWhere(['in', 'c.status', [Cash::STATUS_GIVEN, Cash::STATUS_RECHARGE]]);
  934. }
  935. if ($this->status == Cash::STATUS_REFUSE) {//无效
  936. $query->andWhere(['c.status' => Cash::STATUS_REFUSE]);
  937. }
  938. if ($this->id) {
  939. $query->andWhere(['w.id' => $this->id]);
  940. }
  941. $query->distinct()->orderBy('c.status ASC,c.created_at DESC')->select([
  942. 'c.*', 'u.nickname','u.platform', 'u.avatar_url','u.binding'
  943. ]);
  944. $pagination = pagination_make($query);
  945. $list = $pagination['list'];
  946. foreach($list as &$value){
  947. $value['service_money'] = $value['service_charge'] * $value['price'] / 100;
  948. $value['created_at'] = date('Y-m-d H:i:s', $value['created_at']);
  949. $value['updated_at'] = !empty($value['updated_at']) ? date('Y-m-d H:i:s', $value['updated_at']) : '';
  950. $value['money'] = Cash::getServiceMoney($value);
  951. $sassuser = SaasUser::findOne(['mobile' => $value['binding']]);
  952. $value['avatar_url'] = !empty($sassuser['avatar']) ? $sassuser['avatar'] : $value['avatar_url'];
  953. }
  954. return [
  955. 'code' => 0,
  956. 'msg' => 'success',
  957. 'data' => [
  958. 'data' => $list,
  959. 'pageNo' => $pagination['pageNo'],
  960. 'totalCount' => $pagination['totalCount'],
  961. ],
  962. ];
  963. }
  964. /**
  965. * 获取提现列表
  966. * @return array
  967. */
  968. public function getWorkerCashList(){
  969. $worker = Worker::findOne(['user_id' => $this->user_id, 'status' => 1]);
  970. if(!$worker){
  971. return [
  972. 'code' => 1,
  973. 'msg' => '用户不存在',
  974. ];
  975. }
  976. $query = Cash::find()->alias('c')
  977. ->where(['c.is_delete' => Cash::IS_DELETE_NO, 'c.store_id' => $this->store_id])
  978. ->andWhere([
  979. 'c.user_id' => $this->user_id,
  980. 'c.cash_type' => Cash::IS_CASH_TYPE_WORKER
  981. ]);
  982. if ($this->dateStart) {
  983. $query->andWhere(['>=', 'c.created_at', strtotime($this->dateStart)]);
  984. }
  985. if ($this->dateEnd) {
  986. $query->andWhere(['<=', 'c.created_at', strtotime($this->dateEnd)]);
  987. }
  988. if ($this->status == Cash::STATUS_APPLY and $this->status != '') {//待审核
  989. $query->andWhere(['c.status' => Cash::STATUS_APPLY]);
  990. }
  991. if ($this->status == Cash::STATUS_CONFIRM) {//待打款
  992. $query->andWhere(['c.status' => Cash::STATUS_CONFIRM]);
  993. }
  994. if ($this->status == Cash::STATUS_GIVEN) {//已打款
  995. $query->andWhere(['in', 'c.status', [Cash::STATUS_GIVEN, Cash::STATUS_RECHARGE]]);
  996. }
  997. if ($this->status == Cash::STATUS_REFUSE) {//无效
  998. $query->andWhere(['c.status' => Cash::STATUS_REFUSE]);
  999. }
  1000. $query->distinct()->orderBy('c.status ASC,c.created_at DESC');
  1001. $pagination = pagination_make($query);
  1002. $list = $pagination['list'];
  1003. foreach($list as &$value){
  1004. $value['service_money'] = $value['service_charge'] * $value['price'] / 100;
  1005. $value['created_at'] = date('Y-m-d H:i:s', $value['created_at']);
  1006. $value['updated_at'] = !empty($value['updated_at']) ? date('Y-m-d H:i:s', $value['updated_at']) : '';
  1007. $value['money'] = Cash::getServiceMoney($value);
  1008. }
  1009. return [
  1010. 'code' => 0,
  1011. 'msg' => 'success',
  1012. 'data' => [
  1013. 'data' => $list,
  1014. 'pageNo' => $pagination['pageNo'],
  1015. 'totalCount' => $pagination['totalCount']
  1016. ],
  1017. ];
  1018. }
  1019. }