MchForm.php 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\models;
  8. use app\constants\Kefu;
  9. use app\models\Coupon;
  10. use app\models\Cat;
  11. use app\models\Goods;
  12. use app\models\GoodsCat;
  13. use app\models\ActivityRebateOrderN;
  14. use app\models\ActivityRebateOrderNLog;
  15. use yii\base\Model;
  16. use app\models\Option;
  17. use app\constants\OptionSetting;
  18. use app\models\Order;
  19. use app\models\Mch;
  20. use app\models\MchAudit;
  21. use app\models\MchCommonCat;
  22. use app\models\User;
  23. use app\models\SaasUser;
  24. use app\models\Admin;
  25. use app\models\Cash;
  26. use app\models\MchCat;
  27. use app\models\AccountLog;
  28. use app\models\MchAccountLog;
  29. use app\utils\OrderNo;
  30. use app\models\District;
  31. class MchForm extends Model {
  32. public $store_id;
  33. public $mch_id;
  34. public $saas_id;
  35. public $user_id;
  36. public $user_name;
  37. public $username;
  38. public $password;
  39. public $realname;
  40. public $tel;
  41. public $mch_common_cat_id;
  42. public $wechat_name;
  43. public $is_open;
  44. public $logo;
  45. public $transfer_rate;
  46. public $sort;
  47. public $province_id;
  48. public $city_id;
  49. public $district_id;
  50. public $address;
  51. public $longitude;
  52. public $latitude;
  53. public $begin_time;
  54. public $end_time;
  55. public $saas_user_name;
  56. public $mch_audit;
  57. public $mobile;
  58. public $is_show;
  59. public $id;
  60. public $ids;
  61. public $name;
  62. public $status;
  63. public $order_no;
  64. public $goods_id;
  65. public $goods_name;
  66. public $is_delete;
  67. public $parent_id;
  68. public $pic_url;
  69. public $reason;
  70. public $home_type;
  71. public $lng;
  72. public $lat;
  73. public $dis;
  74. public $orderByDis;
  75. public $orderByAi;
  76. public $form;
  77. public $kefu_id;
  78. public $kefu_auto_reply_img;
  79. public $kefu_auto_reply_text;
  80. public $brands_id;
  81. public function rules() {
  82. return [
  83. [['status', 'id','brands_id'], 'integer'],
  84. [['ids', 'name'], 'string'],
  85. [['store_id', 'mch_id', 'goods_id', 'goods_name', 'saas_id', 'user_id', 'is_delete', 'user_name', 'order_no', 'mobile'], 'safe'],
  86. [['realname', 'tel', 'mch_common_cat_id', 'wechat_name', 'is_open', 'logo', 'transfer_rate',
  87. 'sort', 'province_id', 'city_id', 'district_id', 'address', 'longitude', 'latitude',
  88. 'username', 'password', 'mch_audit', 'is_show', 'begin_time', 'end_time', 'saas_user_name',
  89. 'lng', 'lat', 'dis', 'orderByDis', 'orderByAi',
  90. 'form',
  91. 'parent_id', 'pic_url', 'reason', 'home_type', 'kefu_id', 'kefu_auto_reply_img', 'kefu_auto_reply_text'],
  92. 'safe'
  93. ],
  94. ];
  95. }
  96. public function init() {
  97. parent::init();
  98. if (empty($this->store_id)) {
  99. $this->store_id = get_store_id();
  100. }
  101. }
  102. public function mchSetting() {
  103. $setting = json_decode(Option::get(OptionSetting::MCH_SETTING, $this->store_id, 'store', '{}')['value'], true);
  104. $ret = [
  105. 'mch_reg_form' => $setting['mch_reg_form'] ?? [],
  106. 'mch_reg_text' => $setting['mch_reg_text'] ?? '',
  107. 'mch_goods_audit' => $setting['mch_goods_audit'] ?? 0,
  108. 'mch_order_notice' => $setting['mch_order_notice'] ?? 0,
  109. 'mch_cash_type' => $setting['mch_cash_type'] ?? [0],
  110. 'mch_cash_rate' => $setting['mch_cash_rate'] ?? 0,
  111. 'show_mch_mobile' => !isset($setting['show_mch_mobile']) ? 1 : $setting['show_mch_mobile'],
  112. 'show_mch_address' => !isset($setting['show_mch_address']) ? 1 : $setting['show_mch_address'],
  113. ];
  114. if(!is_array($ret['mch_cash_type'])){
  115. $ret['mch_cash_type'] = [$ret['mch_cash_type']];
  116. }
  117. return $ret;
  118. }
  119. public function mchSettingSave($conf = []) {
  120. Option::set(OptionSetting::MCH_SETTING, json_encode($conf), $this->store_id, 'store');
  121. }
  122. public function mchList() {
  123. try {
  124. $is_delete = 0;
  125. if ($this->is_delete == 1) {
  126. $is_delete = 1;
  127. }
  128. $query = Mch::find()->with(['mchBrands'])->where(['is_delete' => $is_delete, 'store_id' => $this->store_id]);
  129. if (!is_null($this->is_open) && $this->is_open > -1) {
  130. $query->andWhere(['is_open' => $this->is_open]);
  131. }
  132. if (!is_null($this->mch_common_cat_id) && $this->mch_common_cat_id > 0) {
  133. $query->andWhere(['mch_common_cat_id' => $this->mch_common_cat_id]);
  134. }
  135. if ($this->mch_id > 0) {
  136. $query->andWhere(['id' => $this->mch_id]);
  137. }
  138. if (!empty($this->name)) {
  139. $query->andWhere(['like', 'name', trim($this->name)]);
  140. }
  141. if (!empty($this->realname)) {
  142. $query->andWhere(['like', 'realname', trim($this->realname)]);
  143. }
  144. if (!empty($this->tel)) {
  145. $query->andWhere(['like', 'tel', trim($this->tel)]);
  146. }
  147. if (!empty($this->begin_time)) {
  148. $query->andWhere(['>=', 'created_at', strtotime($this->begin_time)]);
  149. }
  150. if (!empty($this->end_time)) {
  151. $query->andWhere(['<=', 'created_at', strtotime($this->end_time)]);
  152. }
  153. if($this->brands_id > -1){
  154. $query->andWhere(['brands_id' => $this->brands_id]);
  155. }
  156. if($this->district_id > 0){
  157. $query->andWhere(['district_id' => $this->district_id]);
  158. }
  159. $query->select('*');
  160. $query->orderBy('id DESC');
  161. if($this->orderByAi){
  162. $query->orderBy('account_money_total DESC, sort DESC, id ASC');
  163. }
  164. if($this->lng && $this->lat){
  165. $queryDis = 'ROUND(st_distance_sphere(point('. $this->lng .', '. $this->lat .'), point(longitude, latitude)), 2)';
  166. if($this->dis){
  167. $query->andWhere($queryDis . " < :dis", [':dis' => $this->dis]);
  168. }
  169. $query->addSelect([$queryDis . ' dis']);
  170. // $query->andWhere(['AND', '`longitude` > 0 AND `latitude` > 0']);
  171. if($this->orderByDis){
  172. $query->orderBy('dis ASC, sort DESC');
  173. }
  174. }
  175. $pagination = pagination_make($query);
  176. $cats = MchCommonCat::find()->where(['store_id' => $this->store_id])->indexBy('id')->all();
  177. foreach ($pagination['list'] as &$item) {
  178. $item['mch_common_cat_name'] = $cats[$item['mch_common_cat_id']] ? $cats[$item['mch_common_cat_id']]['name'] : '-';
  179. $saasUser = SaasUser::findOne([$item['saas_user_id']]);
  180. $item['saas_user'] = $saasUser;
  181. $item['created_at'] = date("Y-m-d H:i:s", $item['created_at']);
  182. $item['updated_at'] = date("Y-m-d H:i:s", $item['updated_at']);
  183. $admin = Admin::findOne(['type_id' => $item['id'], 'type' => Admin::ADMIN_TYPE_MCH, 'is_delete' => 0]);
  184. if($admin->store_id != $item['store_id']){
  185. $admin->store_id = $item['store_id'];
  186. $admin->save();
  187. }
  188. $item['admin'] = $admin;
  189. if(isset($item['dis'])){
  190. $item['dis_str'] = $item['dis'] > 1000 ? (round($item['dis'] / 1000, 2) . 'km') : (round($item['dis'], 0) . 'm');
  191. }
  192. $goods_count = Goods::find()->where(['mch_id' => $item['id'], 'is_delete' => 0])->count();
  193. $item['goods_count'] = $goods_count ?: 0;
  194. }
  195. return [
  196. 'code' => 0,
  197. 'msg' => 'success',
  198. 'data' => $pagination,
  199. // 'q' => $query->createCommand()->getRawSql(),
  200. ];
  201. } catch (\Exception $e) {
  202. \Yii::error($e);
  203. return [
  204. 'code' => 1,
  205. 'msg' => $e->getMessage()
  206. ];
  207. }
  208. }
  209. public function diyMchSelectList(){
  210. $query = Mch::find()->where(['store_id' => $this->store_id,'is_delete' => 0])
  211. ->select('id,name,logo,mch_common_cat_id');
  212. if($this->name){
  213. $query->andWhere(['like','name', $this->name]);
  214. }
  215. if($this->mch_common_cat_id){
  216. $query->andWhere(['mch_common_cat_id' => $this->mch_common_cat_id]);
  217. }
  218. $result = pagination_make($query);
  219. foreach($result['list'] as &$item){
  220. // 搜索入住商商品6个
  221. $item['goods_list'] = Goods::find()->where(['mch_id' => $item['id'],'is_delete'=>0,'status' => 1])->select('id,name,cover_pic,original_price,price')->limit(6)->asArray()->all();
  222. }
  223. return [
  224. 'code' => 0,
  225. 'msg' => 'success',
  226. 'data' => $result,
  227. ];
  228. }
  229. public function mchSelectList() {
  230. $list = Mch::find()->where(['store_id' => $this->store_id])
  231. ->select('id,name,logo,mch_common_cat_id,is_delete')->indexBy('id')->asArray()->all();
  232. foreach($list as &$item){
  233. $item['name'] = $item['id'] . '.' . $item['name'] . ($item['is_delete'] ? '(已删)' : '');
  234. }
  235. return [
  236. 'code' => 0,
  237. 'msg' => 'success',
  238. 'data' => $list,
  239. ];
  240. }
  241. public function mchInfo() {
  242. $mch = Mch::findOne($this->mch_id);
  243. return [
  244. 'code' => 0,
  245. 'msg' => 'success',
  246. 'data' => $mch,
  247. 'dis' => \app\utils\Tools::getDistance($mch->latitude, $mch->longitude, $this->lat, $this->lng),
  248. 'homeTypes' => $this->mchHomeList(),
  249. ];
  250. }
  251. public function mchHomeList() {
  252. $urlPre = '';
  253. if (\Yii::$app instanceof \yii\web\Application){
  254. $urlPre = \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl;
  255. }
  256. $homeTypes = [
  257. $urlPre . '/web/v1/statics/images/mch-home/home1.png',
  258. $urlPre . '/web/v1/statics/images/mch-home/home2.png',
  259. $urlPre . '/web/v1/statics/images/mch-home/home3.png',
  260. ];
  261. return $homeTypes;
  262. }
  263. public function mchHomeSave() {
  264. $mch = Mch::findOne(['id' => $this->id]);
  265. $mch->home_type = (int)$this->home_type;
  266. if (!$mch->save()) {
  267. \Yii::error([__METHOD__, $mch->attributes]);
  268. throw new \Exception('保存失败。' . array_shift($mch->getFirstErrors()));
  269. }
  270. return [
  271. 'code' => 0,
  272. 'msg' => '操作成功!',
  273. ];
  274. }
  275. public function mchSave() {
  276. $t = \Yii::$app->db->beginTransaction();
  277. try {
  278. $mch = $this->id ? Mch::findOne(['id' => $this->id, 'store_id' => $this->store_id]) : new Mch();
  279. if (empty($mch)) {
  280. throw new \Exception('参数错误' . $this->id);
  281. }
  282. if (isset($this->store_id)) {
  283. $mch->store_id = $this->store_id;
  284. }
  285. if (isset($this->user_id)) {
  286. $user = User::findOne($this->user_id);
  287. if (empty($user)) {
  288. throw new \Exception('用户id错误。' . $this->user_id);
  289. }
  290. $saasUser = SaasUser::findOne(['mobile' => $user->binding]);
  291. $mch->user_id = $this->user_id;
  292. $mch->saas_user_id = $saasUser->id;
  293. }
  294. if (isset($this->realname)) {
  295. $mch->realname = $this->realname;
  296. }
  297. if (isset($this->tel)) {
  298. $mch->tel = $this->tel;
  299. }
  300. if (isset($this->mch_common_cat_id)) {
  301. $mch->mch_common_cat_id = $this->mch_common_cat_id;
  302. }
  303. if (isset($this->wechat_name)) {
  304. $mch->wechat_name = $this->wechat_name;
  305. }
  306. if (isset($this->name)) {
  307. $mch->name = $this->name;
  308. }
  309. if (isset($this->is_open)) {
  310. $mch->is_open = $this->is_open;
  311. }
  312. if (isset($this->logo)) {
  313. $mch->logo = $this->logo;
  314. }
  315. if (isset($this->transfer_rate)) {
  316. $mch->transfer_rate = $this->transfer_rate;
  317. }
  318. if (isset($this->sort)) {
  319. $mch->sort = $this->sort;
  320. }
  321. if (isset($this->brands_id) && $this->brands_id > 0) {
  322. $mch->brands_id = $this->brands_id;
  323. }
  324. $mch->service_tel = '';
  325. if (isset($this->province_id) && $this->province_id) {
  326. $district = District::find()->where(['id' => [$this->province_id, $this->city_id, $this->district_id]])->select('name')->column();
  327. $district = implode('', $district);
  328. $mch->district = $district;
  329. $mch->province_id = $this->province_id;
  330. $mch->city_id = $this->city_id;
  331. $mch->district_id = $this->district_id;
  332. $mch->address = $this->address;
  333. $mch->longitude = $this->longitude;
  334. $mch->latitude = $this->latitude;
  335. } else {
  336. $mch->province_id = 0;
  337. $mch->city_id = 0;
  338. $mch->district_id = 0;
  339. $mch->address = '';
  340. }
  341. if (!$mch->save()) {
  342. \Yii::error([__METHOD__, $mch->attributes]);
  343. throw new \Exception('保存失败。' . array_shift($mch->getFirstErrors()));
  344. }
  345. $this->mchAdminSave($this->id ? 0 : 1, $mch, trim($this->username), trim($this->password), $saasUser->id);
  346. $t->commit();
  347. return [
  348. 'code' => 0,
  349. 'msg' => '操作成功!',
  350. 'data' => $mch,
  351. ];
  352. } catch (\Exception $e) {
  353. \Yii::error($e);
  354. $t->rollBack();
  355. return [
  356. 'code' => 1,
  357. 'msg' => $e->getMessage()
  358. ];
  359. }
  360. }
  361. public function mchAdminSave($isAdd, $mch, $username, $password, $saas_user_id) {
  362. $mch_id = $mch->id;
  363. if ($isAdd) {
  364. if (empty($username)) {
  365. throw new \Exception('请输入登陆账户');
  366. }
  367. $is = Admin::find()->where(['username' => $username, 'is_delete' => 0])->one();
  368. if ($is) {
  369. throw new \Exception('账户名称已经存在!请更换' . $username);
  370. }
  371. $admin = new Admin();
  372. $admin->access_token = \Yii::$app->security->generateRandomString();
  373. $admin->username = $username;
  374. $admin->name = $username;
  375. $admin->store_id = $mch->store_id;
  376. $admin->type_id = $mch_id;
  377. $admin->type = Admin::ADMIN_TYPE_MCH;
  378. } else {
  379. if (empty($password)) {
  380. return;
  381. }
  382. $admin = Admin::findOne(['type_id' => $mch_id, 'type' => Admin::ADMIN_TYPE_MCH, 'username' => $username, 'is_delete' => 0]);
  383. if (empty($admin)) {
  384. throw new \Exception('账户不存在');
  385. }
  386. }
  387. $admin->password = \Yii::$app->security->generatePasswordHash($password ?: '123456');
  388. $admin->saas_user_id = $saas_user_id;
  389. if (!$admin->save()) {
  390. throw new \Exception('账户保存失败!' . $username . array_shift($admin->getFirstErrors()));
  391. }
  392. }
  393. public function mchOpen() {
  394. try {
  395. $is_open = $this->is_open;
  396. $id = $this->id;
  397. if (!is_array($id)) {
  398. $id = explode(',', $id);
  399. }
  400. foreach ($id as $item) {
  401. $mch = Mch::findOne($item);
  402. if (!$mch) {
  403. throw new \Exception('参数错误' . $item);
  404. }
  405. $mch->is_open = $is_open;
  406. if (!$mch->save()) {
  407. throw new \Exception('保存失败。' . $item . array_shift($mch->getFirstErrors()));
  408. }
  409. }
  410. return [
  411. 'code' => 0,
  412. 'msg' => 'success',
  413. ];
  414. } catch (\Exception $e) {
  415. \Yii::error($e);
  416. return [
  417. 'code' => 1,
  418. 'msg' => $e->getMessage()
  419. ];
  420. }
  421. }
  422. public function mchDel() {
  423. try {
  424. $id = $this->id;
  425. if (!is_array($id)) {
  426. $id = explode(',', $id);
  427. }
  428. foreach ($id as $item) {
  429. $mch = Mch::findOne($item);
  430. if (!$mch) {
  431. throw new \Exception('参数错误' . $item);
  432. }
  433. $mch->is_delete = 1;
  434. if (!$mch->save()) {
  435. throw new \Exception('保存失败。' . $item . array_shift($mch->getFirstErrors()));
  436. }
  437. }
  438. return [
  439. 'code' => 0,
  440. 'msg' => 'success',
  441. ];
  442. } catch (\Exception $e) {
  443. \Yii::error($e);
  444. return [
  445. 'code' => 1,
  446. 'msg' => $e->getMessage()
  447. ];
  448. }
  449. }
  450. public function mchAuditList() {
  451. try {
  452. $is_delete = 0;
  453. if ($this->is_delete == 1) {
  454. $is_delete = 1;
  455. }
  456. $query = MchAudit::find()->where(['is_delete' => $is_delete, 'store_id' => $this->store_id]);
  457. if (!is_null($this->status) && $this->status > -1) {
  458. $query->andWhere(['status' => $this->status]);
  459. }
  460. if (!is_null($this->mch_common_cat_id) && $this->mch_common_cat_id > 0) {
  461. $query->andWhere(['mch_common_cat_id' => $this->mch_common_cat_id]);
  462. }
  463. if ($this->mch_id > 0) {
  464. $query->andWhere(['mch_id' => $this->mch_id]);
  465. }
  466. if ($this->user_id > 0) {
  467. $query->andWhere(['user_id' => $this->user_id]);
  468. }
  469. if (!empty($this->saas_user_name)) {
  470. $query->andWhere(['saas_user_id' => SaasUser::find()->select('id')->where(['like', 'name', trim($this->saas_user_name)])]);
  471. }
  472. if (!empty($this->name)) {
  473. $query->andWhere(['like', 'name', trim($this->name)]);
  474. }
  475. if (!empty($this->realname)) {
  476. $query->andWhere(['like', 'realname', trim($this->realname)]);
  477. }
  478. if (!empty($this->tel)) {
  479. $query->andWhere(['like', 'tel', trim($this->tel)]);
  480. }
  481. if (!empty($this->begin_time)) {
  482. $query->andWhere(['>=', 'created_at', strtotime($this->begin_time)]);
  483. }
  484. if (!empty($this->end_time)) {
  485. $query->andWhere(['<=', 'created_at', strtotime($this->end_time)]);
  486. }
  487. $query->orderBy('id DESC');
  488. $pagination = pagination_make($query);
  489. $cats = MchCommonCat::find()->where(['store_id' => $this->store_id])->indexBy('id')->all();
  490. foreach ($pagination['list'] as &$item) {
  491. $item['mch_common_cat_name'] = $cats[$item['mch_common_cat_id']] ? $cats[$item['mch_common_cat_id']]['name'] : '-';
  492. $saasUser = SaasUser::findOne([$item['saas_user_id']]);
  493. $item['saas_user'] = $saasUser;
  494. $item['created_at'] = date("Y-m-d H:i:s", $item['created_at']);
  495. $item['updated_at'] = date("Y-m-d H:i:s", $item['updated_at']);
  496. }
  497. return [
  498. 'code' => 0,
  499. 'msg' => 'success',
  500. 'data' => $pagination,
  501. 'q' => $query->createCommand()->getRawSql(),
  502. ];
  503. } catch (\Exception $e) {
  504. \Yii::error($e);
  505. return [
  506. 'code' => 1,
  507. 'msg' => $e->getMessage()
  508. ];
  509. }
  510. }
  511. public function mchAuditStatus() {
  512. $t = \Yii::$app->db->beginTransaction();
  513. try {
  514. $reason = $this->reason;
  515. $status = $this->status;
  516. $id = $this->id;
  517. if (!is_array($id)) {
  518. $id = explode(',', $id);
  519. }
  520. foreach ($id as $item) {
  521. $mchAudit = MchAudit::findOne($item);
  522. if (!$mchAudit) {
  523. throw new \Exception('参数错误' . $item);
  524. }
  525. $mchAudit->reason = $reason ?: '';
  526. $mchAudit->status = $status;
  527. if (!$mchAudit->save()) {
  528. throw new \Exception('保存失败。' . $item . array_shift($mchAudit->getFirstErrors()));
  529. }
  530. if ($status == 1) {
  531. $mchSave = (new MchForm([
  532. 'username' => $mchAudit['username'],
  533. 'password' => $mchAudit['password'],
  534. 'user_id' => $mchAudit['user_id'],
  535. 'name' => $mchAudit['name'],
  536. 'logo' => $mchAudit['logo'],
  537. 'realname' => $mchAudit['realname'],
  538. 'tel' => $mchAudit['tel'],
  539. 'mch_common_cat_id' => $mchAudit['mch_common_cat_id'],
  540. 'wechat_name' => $mchAudit['wechat_name'],
  541. 'form' => $mchAudit['form'],
  542. 'province_id' => $mchAudit['province_id'],
  543. 'city_id' => $mchAudit['city_id'],
  544. 'district_id' => $mchAudit['district_id'],
  545. 'address' => $mchAudit['address'],
  546. 'longitude' => $mchAudit['longitude'],
  547. 'latitude' => $mchAudit['latitude'],
  548. ]))->mchSave();
  549. if ($mchSave['code']) {
  550. throw new \Exception('商户创建失败。' . $mchSave['msg']);
  551. }
  552. $mchAudit->mch_id = $mchSave['data']['id'];
  553. if (!$mchAudit->save()) {
  554. throw new \Exception('审核关联失败。' . $item . array_shift($mchAudit->getFirstErrors()));
  555. }
  556. }
  557. }
  558. $t->commit();
  559. return [
  560. 'code' => 0,
  561. 'msg' => 'success',
  562. ];
  563. } catch (\Exception $e) {
  564. \Yii::error($e);
  565. $t->rollBack();
  566. return [
  567. 'code' => 1,
  568. 'msg' => $e->getMessage()
  569. ];
  570. }
  571. }
  572. public function mchReg() {
  573. $t = \Yii::$app->db->beginTransaction();
  574. try {
  575. $has = MchAudit::find()->where(['user_id' => $this->user_id, 'status' => 0])->one();
  576. if($has){
  577. throw new \Exception('禁止重复申请。');
  578. }
  579. $mch = new MchAudit();
  580. $mch->store_id = $this->store_id;
  581. $mch->user_id = $this->user_id;
  582. $mch->saas_user_id = $this->saas_id;
  583. $mch->realname = $this->realname;
  584. $mch->tel = $this->tel;
  585. $mch->mch_common_cat_id = $this->mch_common_cat_id;
  586. $mch->wechat_name = $this->wechat_name;
  587. $mch->username = $this->username;
  588. $mch->password = $this->password;
  589. $mch->form = is_array($this->form) ? json_encode($this->form) : $this->form;
  590. if (isset($this->name)) {
  591. $mch->name = $this->name;
  592. }
  593. if (isset($this->logo)) {
  594. $mch->logo = $this->logo;
  595. }
  596. if (isset($this->province_id) && $this->province_id) {
  597. $district = District::find()->where(['id' => [$this->province_id, $this->city_id, $this->district_id]])->select('name')->column();
  598. $district = implode('', $district);
  599. $mch->district = $district;
  600. $mch->province_id = $this->province_id;
  601. $mch->city_id = $this->city_id;
  602. $mch->district_id = $this->district_id;
  603. $mch->address = $this->address;
  604. $mch->longitude = $this->longitude;
  605. $mch->latitude = $this->latitude;
  606. }
  607. if (!$mch->save()) {
  608. \Yii::error([__METHOD__, $mch->attributes]);
  609. throw new \Exception('保存失败。' . array_shift($mch->getFirstErrors()));
  610. }
  611. $t->commit();
  612. return [
  613. 'code' => 0,
  614. 'msg' => '操作成功!',
  615. 'data' => $mch,
  616. ];
  617. } catch (\Exception $e) {
  618. \Yii::error($e);
  619. $t->rollBack();
  620. return [
  621. 'code' => 1,
  622. 'msg' => $e->getMessage()
  623. ];
  624. }
  625. }
  626. public function mchAuditDel() {
  627. try {
  628. $id = $this->id;
  629. if (!is_array($id)) {
  630. $id = explode(',', $id);
  631. }
  632. foreach ($id as $item) {
  633. $mchAudit = MchAudit::findOne($item);
  634. if (!$mchAudit) {
  635. throw new \Exception('参数错误' . $item);
  636. }
  637. $mchAudit->is_delete = 1;
  638. if (!$mchAudit->save()) {
  639. throw new \Exception('保存失败。' . $item . array_shift($mchAudit->getFirstErrors()));
  640. }
  641. }
  642. return [
  643. 'code' => 0,
  644. 'msg' => 'success',
  645. ];
  646. } catch (\Exception $e) {
  647. \Yii::error($e);
  648. return [
  649. 'code' => 1,
  650. 'msg' => $e->getMessage()
  651. ];
  652. }
  653. }
  654. public function mchCommonCatList() {
  655. try {
  656. $is_delete = 0;
  657. if ($this->is_delete == 1) {
  658. $is_delete = 1;
  659. }
  660. $query = MchCommonCat::find()->where(['is_delete' => $is_delete, 'store_id' => $this->store_id]);
  661. if (!is_null($this->is_show) && $this->is_show > -1) {
  662. $query->andWhere(['is_show' => $this->is_show]);
  663. }
  664. if (!empty($this->name)) {
  665. $query->andWhere(['like', 'name', trim($this->name)]);
  666. }
  667. if (!empty($this->begin_time)) {
  668. $query->andWhere(['>=', 'created_at', strtotime($this->begin_time)]);
  669. }
  670. if (!empty($this->end_time)) {
  671. $query->andWhere(['<=', 'created_at', strtotime($this->end_time)]);
  672. }
  673. $query->orderBy('sort DESC, id DESC');
  674. $list = $query->asArray()->all();
  675. return [
  676. 'code' => 0,
  677. 'msg' => 'success',
  678. 'data' => ['list' => $list],
  679. // 'q' => $query->createCommand()->getRawSql(),
  680. ];
  681. } catch (\Exception $e) {
  682. \Yii::error($e);
  683. return [
  684. 'code' => 1,
  685. 'msg' => $e->getMessage()
  686. ];
  687. }
  688. }
  689. public function mchCommonCatSelectList($indexBy = 1) {
  690. $query = MchCommonCat::find()->where(['is_delete' => 0, 'store_id' => $this->store_id])
  691. ->select('id,name,is_show');
  692. if($indexBy){
  693. $query->indexBy('id');
  694. }
  695. $list = $query->orderBy('sort DESC, id DESC')->asArray()->all();
  696. foreach($list as &$item){
  697. if(!$item['is_show']){
  698. $item['name'] .= '(已隐藏)';
  699. }
  700. }
  701. return [
  702. 'code' => 0,
  703. 'msg' => 'success',
  704. 'data' => $list,
  705. ];
  706. }
  707. public function mchCommonCatSave() {
  708. try {
  709. $mchCommonCat = $this->id ? MchCommonCat::findOne(['id' => $this->id, 'store_id' => $this->store_id]) : new MchCommonCat();
  710. if (empty($mchCommonCat)) {
  711. throw new \Exception('参数错误' . $this->id);
  712. }
  713. $mchCommonCat->name = $this->name;
  714. $mchCommonCat->sort = $this->sort ?: 0;
  715. $mchCommonCat->is_show = $this->is_show;
  716. $mchCommonCat->store_id = $this->store_id;
  717. if (!$mchCommonCat->save()) {
  718. \Yii::error([__METHOD__, $mchCommonCat->attributes]);
  719. throw new \Exception('保存失败。' . array_shift($mchCommonCat->getFirstErrors()));
  720. }
  721. return [
  722. 'code' => 0,
  723. 'msg' => '操作成功!'
  724. ];
  725. } catch (\Exception $e) {
  726. \Yii::error($e);
  727. return [
  728. 'code' => 1,
  729. 'msg' => $e->getMessage()
  730. ];
  731. }
  732. }
  733. public function mchCommonCatShow() {
  734. try {
  735. $is_show = $this->is_show;
  736. $id = $this->id;
  737. if (!is_array($id)) {
  738. $id = explode(',', $id);
  739. }
  740. foreach ($id as $item) {
  741. $mchCommonCat = MchCommonCat::findOne($item);
  742. if (!$mchCommonCat) {
  743. throw new \Exception('参数错误' . $item);
  744. }
  745. $mchCommonCat->is_show = $is_show;
  746. if (!$mchCommonCat->save()) {
  747. throw new \Exception('保存失败。' . $item . array_shift($mchCommonCat->getFirstErrors()));
  748. }
  749. }
  750. return [
  751. 'code' => 0,
  752. 'msg' => 'success',
  753. ];
  754. } catch (\Exception $e) {
  755. \Yii::error($e);
  756. return [
  757. 'code' => 1,
  758. 'msg' => $e->getMessage()
  759. ];
  760. }
  761. }
  762. public function mchCommonCatDel() {
  763. try {
  764. $id = $this->id;
  765. if (!is_array($id)) {
  766. $id = explode(',', $id);
  767. }
  768. foreach ($id as $item) {
  769. $mchCommonCat = MchCommonCat::findOne($item);
  770. if (!$mchCommonCat) {
  771. throw new \Exception('参数错误' . $item);
  772. }
  773. $mchCommonCat->is_delete = 1;
  774. if (!$mchCommonCat->save()) {
  775. throw new \Exception('保存失败。' . $item . array_shift($mchCommonCat->getFirstErrors()));
  776. }
  777. }
  778. return [
  779. 'code' => 0,
  780. 'msg' => 'success',
  781. ];
  782. } catch (\Exception $e) {
  783. \Yii::error($e);
  784. return [
  785. 'code' => 1,
  786. 'msg' => $e->getMessage()
  787. ];
  788. }
  789. }
  790. public function mchGoodsAudit() {
  791. $t = \Yii::$app->db->beginTransaction();
  792. try {
  793. $status = $this->status;
  794. $id = $this->id;
  795. if (!is_array($id)) {
  796. $id = explode(',', $id);
  797. }
  798. foreach ($id as $item) {
  799. $goods = Goods::findOne($item);
  800. if (!$goods) {
  801. throw new \Exception('参数错误' . $item);
  802. }
  803. $goods->mch_audit = 0;
  804. $goods->mch_audit_time = 0;
  805. if ($status == 1) {
  806. $goods->status = Goods::STATUS_NORMAL;
  807. }
  808. if (!$goods->save()) {
  809. throw new \Exception('保存失败。' . $item . array_shift($goods->getFirstErrors()));
  810. }
  811. }
  812. $t->commit();
  813. return [
  814. 'code' => 0,
  815. 'msg' => 'success',
  816. ];
  817. } catch (\Exception $e) {
  818. \Yii::error($e);
  819. $t->rollBack();
  820. return [
  821. 'code' => 1,
  822. 'msg' => $e->getMessage()
  823. ];
  824. }
  825. }
  826. public static function goodsCatList($mch_id = 1, $is_show = -1){
  827. $res = [];
  828. $query = MchCat::find()->where([
  829. 'is_delete' => 0,
  830. 'mch_id' => $mch_id
  831. ])->orderBy(['sort'=>SORT_ASC]);
  832. if ($is_show > -1) {
  833. $query->andWhere([
  834. 'is_show' => $is_show
  835. ]);
  836. }
  837. $cat_list = $query->asArray()->all();
  838. if ($cat_list) {
  839. $res = buildTree($cat_list);
  840. }
  841. return $res;
  842. }
  843. public function goodsCatSave(){
  844. $cat = $this->id ? MchCat::findOne(['id' => $this->id, 'mch_id' => $this->mch_id]) : new MchCat();
  845. if (empty($cat)) {
  846. throw new \Exception('参数错误' . $this->id);
  847. }
  848. $cat->parent_id = $this->parent_id;
  849. $cat->is_show = $this->is_show;
  850. if ($this->is_show == 0 && $this->id) {
  851. // 产品分类隐藏同时下架该分类下所有商品
  852. $goods_ids = MchGoodsCat::find()->where(['cat_id' => $this->id])->select('goods_id')->asArray()->all();
  853. Goods::updateAll(['status' => Goods::STATUS_DISABLE],['in', 'id', array_column($goods_ids, 'goods_id')]);
  854. }
  855. $cat->name = $this->name;
  856. $cat->pic_url = $this->pic_url;
  857. $cat->sort = $this->sort;
  858. $cat->mch_id = $this->mch_id;
  859. if ($cat->save()) {
  860. return [
  861. 'code' => 0,
  862. 'msg' => '提交成功'
  863. ];
  864. } else {
  865. return [
  866. 'code' => 0,
  867. 'msg' => '保存失败' . array_shift($cat->getFirstErrors()),
  868. ];
  869. }
  870. }
  871. public function goodsCatStatus($id, $status = 1){
  872. try {
  873. if (!is_array($id)) {
  874. $id = explode(',', $id);
  875. }
  876. foreach ($id as $item) {
  877. $mchCat = MchCat::findOne($item);
  878. if (!$mchCat) {
  879. throw new \Exception('参数错误' . $item);
  880. }
  881. if($status == 0 || $status == 1){
  882. $mchCat->is_show = $status;
  883. }else{
  884. $mchCat->is_delete = 1;
  885. }
  886. if (!$mchCat->save()) {
  887. throw new \Exception('保存失败。' . $item . array_shift($mchCat->getFirstErrors()));
  888. }
  889. }
  890. return [
  891. 'code' => 0,
  892. 'msg' => 'success',
  893. ];
  894. } catch (\Exception $e) {
  895. \Yii::error($e);
  896. return [
  897. 'code' => 1,
  898. 'msg' => $e->getMessage()
  899. ];
  900. }
  901. }
  902. //发放佣金
  903. public static function accountMoneyAdd($order) {
  904. if(!$order){
  905. return [
  906. 'code' => 1,
  907. 'msg' => '入驻商订单不存在或已发放',
  908. ];
  909. }
  910. $mch_id = $order->mch_id;
  911. if(!$mch_id){
  912. return [
  913. 'code' => 404,
  914. 'msg' => '非入驻商订单',
  915. ];
  916. }
  917. $order_id = $order->id;
  918. $t = \Yii::$app->db->beginTransaction();
  919. try{
  920. $order->mch_is_price = 1;
  921. $order->mch_is_price_time = time();
  922. $save = $order->save();
  923. if(!$save){
  924. throw new \Exception('入驻商佣金发放状态修改失败' . array_shift($order->getFirstErrors()));
  925. }
  926. $mch = Mch::findOne($mch_id);
  927. $pay_price = $order instanceof \app\plugins\scanCodePay\models\Order ? $order->total_price : $order->pay_price;
  928. $profit = sprintf("%.2f", $pay_price * $mch->transfer_rate / 100);
  929. $amount = $pay_price - $profit;
  930. $desc = [];
  931. //
  932. $share_price = (float)$order->first_price + (float)$order->second_price + (float)$order->third_price;
  933. if($share_price > 0){
  934. $amount -= $share_price;
  935. $desc[] = '分销佣金:' . $share_price;
  936. }
  937. //同城配送费用
  938. if(isset($order->is_delivery) && $order->is_delivery){
  939. $delivery_info = \app\models\DeliveryInfo::findOne(['order_no' => $order->order_no]);
  940. $express_price = (float)$delivery_info['fee'];
  941. if($express_price > 0){
  942. $amount -= $express_price;
  943. $desc[] = '同城配送费用:' . $express_price;
  944. }
  945. }
  946. $desc = implode(';', $desc);
  947. $amount = $amount <= 0 ? 0 : $amount;
  948. $saveLog = MchAccountLog::saveLog($mch_id, $order->user_id, $amount, AccountLog::LOG_TYPE_INCOME, $order_id, $order->order_no, $desc, $profit);
  949. if($saveLog['code']){
  950. throw new \Exception($saveLog['msg']);
  951. }
  952. $t->commit();
  953. return [
  954. 'code' => 0,
  955. 'msg' => 'ok',
  956. ];
  957. } catch (\Exception $ex) {
  958. debug_log([__METHOD__, __LINE__, $order->id, $ex->getMessage()], __CLASS__ . '.log');
  959. $t->rollBack();
  960. return [
  961. 'code' => 1,
  962. 'msg' => '操作失败,' . $ex->getMessage(),
  963. ];
  964. }
  965. }
  966. //佣金
  967. public function accountLog() {
  968. try {
  969. $query = MchAccountLog::find()->where(['mch_id' => $this->mch_id]);
  970. if ($this->order_no) {
  971. $query->andWhere(['like', 'order_no', $this->order_no]);
  972. }
  973. if (!empty($this->begin_time)) {
  974. $query->andWhere(['>=', 'created_at', strtotime($this->begin_time)]);
  975. }
  976. if (!empty($this->end_time)) {
  977. $query->andWhere(['<=', 'created_at', strtotime($this->end_time)]);
  978. }
  979. $query->orderBy('id DESC');
  980. $pagination = pagination_make($query);
  981. foreach ($pagination['list'] as &$item) {
  982. $item['created_at'] = date("Y-m-d H:i:s", $item['created_at']);
  983. }
  984. return [
  985. 'code' => 0,
  986. 'msg' => 'success',
  987. 'data' => $pagination,
  988. 'mch' => Mch::findOne($this->mch_id),
  989. // 'q' => $query->createCommand()->getRawSql(),
  990. ];
  991. } catch (\Exception $e) {
  992. \Yii::error($e);
  993. return [
  994. 'code' => 1,
  995. 'msg' => $e->getMessage()
  996. ];
  997. }
  998. }
  999. //提现
  1000. public function mchCashSubmit($price, $type, $user_id = 0, $name = '', $account = '', $bank = '') {
  1001. $mch_id = $this->mch_id;
  1002. $exit = Cash::find()->andWhere(['=', 'status', 0])->andWhere(['mch_id' => $mch_id, 'cash_type' => Cash::IS_CASH_TYPE_MCH])->exists();
  1003. if ($exit) {
  1004. // return [
  1005. // 'code' => 1,
  1006. // 'msg' => '尚有未完成的提现申请'
  1007. // ];
  1008. }
  1009. $mch = Mch::findOne($mch_id);
  1010. $conf = $this->mchSetting();
  1011. if (!$price) {
  1012. return [
  1013. 'code' => 1,
  1014. 'msg' => '参数非法1',
  1015. 'f' => func_get_args(),
  1016. 'c' => $conf,
  1017. ];
  1018. }
  1019. $service_charge = $price * $conf['mch_cash_rate'] / 100;
  1020. $t = \Yii::$app->db->beginTransaction();
  1021. try {
  1022. $cash = new Cash();
  1023. $cash->order_no = OrderNo::getOrderNo(OrderNo::ORDER_CASH);
  1024. $cash->is_delete = 0;
  1025. $cash->status = 0;
  1026. $cash->mch_id = $mch_id;
  1027. $cash->price = $price;
  1028. $cash->created_at = time();
  1029. $cash->user_id = $user_id;
  1030. $cash->store_id = $mch->store_id;
  1031. $cash->type = $type;
  1032. $cash->name = $name;
  1033. $cash->mobile = $account;
  1034. $cash->bank_name = $bank;
  1035. $cash->pay_time = 0;
  1036. $cash->service_charge = $conf['mch_cash_rate'];
  1037. $cash->cash_type = Cash::IS_CASH_TYPE_MCH;
  1038. if (!$cash->save()) {
  1039. \Yii::error([__METHOD__, $cash->getErrors()]);
  1040. throw new \Exception('入驻商提现保存失败' . array_shift($cash->getFirstErrors()));
  1041. }
  1042. $saveLog = MchAccountLog::saveLog($mch_id, (int)$user_id, $price, AccountLog::LOG_TYPE_EXPEND, 0, $cash->order_no, '提现', $service_charge);
  1043. if($saveLog['code']){
  1044. throw new \Exception($saveLog['msg']);
  1045. }
  1046. $t->commit();
  1047. return [
  1048. 'code' => 0,
  1049. 'msg' => '操作成功'
  1050. ];
  1051. } catch (\Exception $e) {
  1052. \Yii::error($e);
  1053. debug_log([__METHOD__, __LINE__, $e->getMessage()], __CLASS__ . '.log');
  1054. $t->rollBack();
  1055. return [
  1056. 'code' => 1,
  1057. 'msg' => '操作失败,' . $e->getMessage()
  1058. ];
  1059. }
  1060. }
  1061. public function getKefuInfo()
  1062. {
  1063. $mch_id = $this->mch_id;
  1064. $mch = Mch::findOne($mch_id);
  1065. if (!$mch) {
  1066. return [
  1067. 'code' => 1,
  1068. 'msg' => '数据不存在',
  1069. ];
  1070. }
  1071. $kefu_info = json_decode($mch->kefu_info ?: '', true);
  1072. if (empty($kefu_info)) {
  1073. $kefu_info = [
  1074. 'kefu_id' => '',
  1075. 'kefu_auto_reply_img' => '',
  1076. 'kefu_auto_reply_text' => '',
  1077. ];
  1078. }
  1079. $is_show_kefu_download = Option::get('is_show_kefu_download', 0, 'saas', 1)['value'];
  1080. return [
  1081. 'code' => 0,
  1082. 'msg' => 'success',
  1083. 'data'=> [
  1084. 'kefu_id' => $kefu_info['kefu_id'] ?: '',
  1085. 'kefu_auto_reply_img' => $kefu_info['kefu_auto_reply_img'] ?: '',
  1086. 'kefu_auto_reply_text' => $kefu_info['kefu_auto_reply_text'] ?: '',
  1087. 'is_show_kefu_download' => intval($is_show_kefu_download)
  1088. ]
  1089. ];
  1090. }
  1091. public function setKefuInfo()
  1092. {
  1093. $kefu_id = $this->kefu_id;
  1094. $kefu_auto_reply_img = $this->kefu_auto_reply_img;
  1095. $kefu_auto_reply_text = $this->kefu_auto_reply_text;
  1096. $mch_id = $this->mch_id;
  1097. $mch = Mch::findOne($mch_id);
  1098. if (!$mch) {
  1099. return [
  1100. 'code' => 1,
  1101. 'msg' => '数据不存在',
  1102. ];
  1103. }
  1104. $kefu_info = [
  1105. 'kefu_id' => $kefu_id ?: '',
  1106. 'kefu_auto_reply_img' => $kefu_auto_reply_img ?: '',
  1107. 'kefu_auto_reply_text' => $kefu_auto_reply_text ?: '',
  1108. ];
  1109. if (!empty($kefu_id)) {
  1110. if (!preg_match('/^1[3456789]\d{9}$/i', $kefu_id)) {
  1111. return [
  1112. 'code' => 1,
  1113. 'msg' => '客服手机号格式错误',
  1114. ];
  1115. }
  1116. $url = Kefu::API_HOST;
  1117. $host = \str_replace(['http://', 'https://'], '', \Yii::$app->request->hostInfo);
  1118. $res = http_post($url . '/api/regKefu', [
  1119. 'form_params' => [
  1120. 'token' => \Yii::$app->getKefuApiToken(),
  1121. 'host' => $host,
  1122. 'mobile' => $kefu_id,
  1123. 'kefu_auto_reply_img' => $kefu_auto_reply_img,
  1124. 'kefu_auto_reply_text' => $kefu_auto_reply_text,
  1125. ]
  1126. ]);
  1127. if ($res->getStatusCode() != 200) {
  1128. return [
  1129. 'code' => 1,
  1130. 'msg' => '请求出错!',
  1131. ];
  1132. }
  1133. $content = json_decode((string)$res->getBody(), true);
  1134. if ($content['code'] == 0) {
  1135. $mch->kefu_info = json_encode($kefu_info, JSON_UNESCAPED_UNICODE);
  1136. $mch->save();
  1137. }
  1138. } else {
  1139. $mch->kefu_info = json_encode($kefu_info, JSON_UNESCAPED_UNICODE);
  1140. $mch->save();
  1141. $content = [
  1142. 'code' => 0,
  1143. 'msg' => '保存成功',
  1144. ];
  1145. }
  1146. return $content;
  1147. }
  1148. //入驻商访客key
  1149. public static function cacheKeyVisit($mch_id, $date = '') {
  1150. $key = implode('_', ['mch_visit_date', $mch_id, $date]);
  1151. return $key;
  1152. }
  1153. //入驻商访客
  1154. public function mchVisit($date = '', $add = 0) {
  1155. $key = self::cacheKeyVisit($this->mch_id, $date);
  1156. $val = cache()->get($key);
  1157. if($add){
  1158. $val += $add;
  1159. cache()->set($key, $val, 86400 * 30);
  1160. }
  1161. return $val;
  1162. }
  1163. }