StoreAdminForm.php 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\alliance\models\store;
  8. use app\constants\AdminPickLink;
  9. use app\models\Admin;
  10. use app\models\BrowseLog;
  11. use app\models\Cart;
  12. use app\models\Cat;
  13. use app\models\Goods;
  14. use app\models\Option;
  15. use app\models\Order;
  16. use app\models\OrderDetail;
  17. use app\models\OrderGoodsCancel;
  18. use app\models\Store;
  19. use app\models\StoreCloud;
  20. use app\models\StoreMini;
  21. use app\models\StoreReOrder;
  22. use app\models\User;
  23. use app\models\UserShareLog;
  24. use app\models\WechatConfig;
  25. use app\modules\alliance\behaviors\StoreAdmin;
  26. use EasyWeChat\Factory;
  27. use EasyWeChat\Kernel\BaseClient;
  28. use yii\base\Model;
  29. use yii\db\Expression;
  30. use app\models\OrderRefund;
  31. use app\utils\ShareQrcode;
  32. class StoreAdminForm extends Model
  33. {
  34. public $date_range;
  35. public $start_date;
  36. public $end_date;
  37. public $wechat;
  38. public $type;
  39. public $tab;
  40. public $logo;
  41. public $name;
  42. public $coordinate;
  43. public $address;
  44. public $store_id;
  45. public $wechat_config;
  46. public $rate;
  47. // public $is_auth_trans;
  48. public $cloud_is_update;
  49. public function rules()
  50. {
  51. return [
  52. [['start_date', 'end_date', 'type', 'tab', 'store_id', 'cloud_is_update'], 'integer'],
  53. [['logo', 'name', 'coordinate', 'address', 'rate'], 'string']
  54. ];
  55. }
  56. public function initWX()
  57. {
  58. $type = 1;
  59. $store_id = $this->store_id;
  60. $store = Store::findOne($this->store_id);
  61. if (\Yii::$app->prod_is_dandianpu()) {
  62. $one_store_wechat_appid = Option::get('one_store_wechat_appid', 0, 'saas')['value'];
  63. $one_store_wechat_secret = Option::get('one_store_wechat_secret', 0, 'saas')['value'];
  64. $this->wechat_config = (object)[
  65. 'app_id' => $one_store_wechat_appid,
  66. 'app_secret' => $one_store_wechat_secret
  67. ];
  68. }elseif($store->business_model == 2){
  69. $wechat_appid = Option::get('platform_appid', 0, 'saas')['value'];
  70. $wechat_secret = Option::get('platform_key', 0, 'saas')['value'];
  71. $this->wechat_config = (object)[
  72. 'app_id' => $wechat_appid,
  73. 'app_secret' => $wechat_secret
  74. ];
  75. } elseif (!\Yii::$app->isSaas()) {
  76. $this->wechat_config = WechatConfig::findOne(['store_id' => $store_id, 'type' => $type]);
  77. } else {
  78. $this->wechat_config = WechatConfig::findOne(['store_id' => $store_id, 'type' => $type]);
  79. $platform_third_appid = Option::get('platform_third_appid', 0, 'saas')['value'];
  80. $platform_third_secret = Option::get('platform_third_secret', 0, 'saas')['value'];
  81. $platform_encodingAesKey = Option::get('platform_encodingAesKey', 0, 'saas')['value'];
  82. $platform_token = Option::get('platform_token', 0, 'saas')['value'];
  83. $config = [
  84. 'app_id' => $platform_third_appid,
  85. 'secret' => $platform_third_secret,
  86. 'token' => $platform_token,
  87. 'aes_key' => $platform_encodingAesKey
  88. ];
  89. $openPlatform = Factory::openPlatform($config);
  90. $wechat_config = WechatConfig::findOne(['store_id' => $store_id, 'type' => $type]);
  91. if ($wechat_config->app_id) {
  92. $base_info = $openPlatform->getAuthorizer($wechat_config->app_id);
  93. $this->wechat = $openPlatform->miniProgram($wechat_config->app_id, $base_info['authorization_info']['authorizer_refresh_token']);
  94. } else {
  95. $this->wechat = null;
  96. }
  97. return;
  98. }
  99. if ($this->wechat_config) {
  100. $config = [
  101. 'app_id' => $this->wechat_config->app_id,
  102. 'secret' => $this->wechat_config->app_secret,
  103. 'response_type' => 'array'
  104. ];
  105. if (empty($config['app_id']) || empty($config['secret'])) {
  106. $this->wechat = null;
  107. } else {
  108. $this->wechat = Factory::miniProgram($config);
  109. }
  110. }
  111. }
  112. public function getQrcode($store_id, $scene = '', $data = null) {
  113. $save_root = \Yii::$app->basePath . '/web/temp/';
  114. if (!is_dir($save_root)) {
  115. mkdir($save_root);
  116. file_put_contents($save_root . '.gitignore', "*\r\n!.gitignore");
  117. }
  118. $version = cyy_version();
  119. $save_name = sha1("v={$version}&store_id={$store_id}&type=qrcode_share_store") . '.jpg';
  120. $pic_url = \Yii::$app->request->hostInfo . \Yii::$app->request->baseUrl . '/web/temp/' . $save_name;
  121. $wdcp_patch = false;
  122. $wdcp_patch_file = \Yii::$app->basePath . '/patch/wdcp.json';
  123. if (file_exists($wdcp_patch_file)) {
  124. $wdcp_patch = json_decode(file_get_contents($wdcp_patch_file), true);
  125. if ($wdcp_patch && in_array(\Yii::$app->request->hostName, $wdcp_patch)) {
  126. $wdcp_patch = true;
  127. } else {
  128. $wdcp_patch = false;
  129. }
  130. }
  131. if ($wdcp_patch) {
  132. $pic_url = str_replace('http://', 'https://', $pic_url);
  133. }
  134. if (file_exists($save_root . $save_name)) {
  135. return [
  136. 'code' => 0,
  137. 'msg' => 'success',
  138. 'data' => [
  139. 'url'=>$pic_url . '?v=' . time()
  140. ]
  141. ];
  142. }
  143. /** @var Factory $wechat */
  144. $data = [
  145. 'width' => 430,
  146. ];
  147. $scene = "store:$store_id";
  148. $wechat = $this->wechat;
  149. $response = $wechat->app_code->getUnlimit($scene, $data);
  150. \Yii::warning($response);
  151. // 保存小程序码到文件
  152. if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
  153. $response->saveAs($save_root, $save_name);
  154. //返回图片
  155. return [
  156. 'code' => 0,
  157. 'data' => [
  158. 'url' => $pic_url
  159. ]
  160. ];
  161. } else {
  162. //返回文字
  163. return [
  164. 'code' => 1,
  165. 'msg' => $response['errmsg'],
  166. ];
  167. }
  168. }
  169. public function storeInfo(){
  170. /**
  171. * 判断是否为管理员
  172. * 店铺logo 店铺名称 店铺管理员
  173. * 访客数 今昨日
  174. * 订单数量 今昨日
  175. * 成交金额 今昨日
  176. * 补货通知[]
  177. * 待付款数量 待发货数量 待售后数量 待评价数量 待处理数量
  178. **/
  179. try {
  180. // //店铺logo 店铺名称
  181. // $saasUser = get_saas_user();
  182. // // 根据admin表中手机号判断当前是否为客户端管理员,后期需添加admin表中的手机号编辑
  183. // $store_admin = Admin::find()->where(['mobile' => $saasUser->mobile, 'is_delete' => 0, 'type' => 'store'])->orderBy('id DESC')->one();
  184. // if($store_admin){
  185. // $store_info = Store::find()->where(['id' => $store_admin->type_id, 'is_delete' => 0])
  186. // ->select('id, name, logo, end_time')->asArray()->one();
  187. // }else{
  188. // $store_info = '';
  189. // }
  190. //
  191. // if (empty($store_info)) {
  192. // throw new \Exception("非商城管理员");
  193. // }
  194. //
  195. //
  196. // $this->store_id = $store_info['id'];
  197. $store_info = Store::find()->where(['id' => $this->store_id, 'is_delete' => 0])
  198. ->select('id, name, logo, end_time, business_model, kefu_id')->asArray()->one();
  199. if (empty($store_info)) {
  200. throw new \Exception("非商城管理员");
  201. }
  202. $mini_qr = '';
  203. $this->initWX();
  204. if ($this->wechat) {
  205. $page = "pages/home/home";
  206. //20240816生成码后前端参数识别不了 从store改为store_id
  207. $scene = "store_id:{$this->store_id}";
  208. if ($store_info['business_model'] == 2) { //平台运营
  209. $page = 'pages/shop/shopIndex';
  210. $scene = "store_id:{$this->store_id}";
  211. } elseif ($store_info['business_model'] == 3) { //当面付
  212. $page = 'pages/shop/shopDetail';
  213. $scene = "store_id:{$this->store_id}";
  214. } elseif ($store_info['business_model'] == 4) { //点餐
  215. $page = 'alipay-order/orderMeal/orderMeal';
  216. $scene = "md_id:-1,store_id:{$this->store_id}";
  217. }
  218. $res = ShareQrcode::wxQrcode($page, $scene, 600, false, false, $store_info['id']);
  219. if ($res['code'] === 0) {
  220. $mini_qr = $res['url_path'];
  221. }
  222. }
  223. $saas_name = !empty(get_saas_user()->name) ? get_saas_user()->name : "未设置";
  224. //店铺管理员名称
  225. $store_info['user_name'] = $saas_name;
  226. //获取昨日凌晨时间
  227. $yet = strtotime(date('Y-m-d')) - (60 * 60 * 24);
  228. //获取今日凌晨时间
  229. $td = strtotime(date('Y-m-d'));
  230. //获取明日凌晨时间
  231. $tot = strtotime(date('Y-m-d')) + (60 * 60 * 24);
  232. $timestamp = time();
  233. $day = [
  234. 'begin_date' => date('Ymd', $timestamp),
  235. 'end_date' => date('Ymd', $timestamp),
  236. ];
  237. $lastday = [
  238. 'begin_date' => date('Ymd', strtotime("-1 day", $timestamp)),
  239. 'end_date' => date('Ymd', strtotime("-1 day", $timestamp)),
  240. ];
  241. //访客数
  242. //今日访客
  243. try {
  244. $today_visit = $this->getVisit($day);
  245. } catch (\Exception $e) {
  246. $today_visit = 0;
  247. }
  248. try {
  249. //昨日访客
  250. $yes_visit = $this->getVisit($lastday);
  251. } catch (\Exception $e) {
  252. $yes_visit = 0;
  253. }
  254. //订单数
  255. $order_query = Order::find()->where(['store_id' => $store_info['id'], 'is_delete' => 0, 'is_show'=>1])
  256. ->andWhere([
  257. 'trade_status' => [
  258. Order::ORDER_FLOW_NO_SEND,
  259. Order::ORDER_FLOW_SEND,
  260. Order::ORDER_FLOW_CONFIRM
  261. ],
  262. 'is_pay' => Order::IS_PAY_TRUE
  263. ])->select('id, trade_status, created_at');
  264. //成交额
  265. $money_query = clone $order_query;
  266. //今日订单数
  267. $order_count = $order_query->count();
  268. //昨日订单数
  269. $yet_order_count = $order_query->andWhere(['and', ['>', 'created_at', $yet], ['>','created_at', $td]])->count();
  270. //成交额
  271. $money_count = $money_query->sum('pay_price') ?: 0;
  272. //昨日成交额
  273. $yet_money_count = $order_query->andWhere(['and', ['>','created_at',$yet], ['>','created_at',$td]])->sum('pay_price') ?: 0;
  274. //通知
  275. $goods = Goods::find()->where(['store_id' => $store_info['id'], 'status' => 1, 'is_delete' => 0])->select('id, goods_num, attr, use_attr, goods_no')->asArray()->all();
  276. $arr = [];
  277. $i = 0;
  278. foreach($goods as $item){
  279. // 判断无规格商品的总库存
  280. if ($item['goods_num'] * 1 < 10 && $item['use_attr'] == 0) {
  281. $arr[$i]['id'] = $item['id'];
  282. $arr[$i]['notice'] = 'id:' . $item['id'] . ' 货号:' . $item['goods_no'] . "库存不足,请及时补货";
  283. $i++;
  284. }
  285. // 判断有规格商品的总库存
  286. if ($item['use_attr'] != 0 && !empty($item['attr'])) {
  287. $attrs = json_decode($item['attr'],true);
  288. foreach($attrs as $attr){
  289. if ($attr['num']*1 < 10) {
  290. $arr[$i]['id'] = $item['id'];
  291. $arr[$i]['notice'] = 'id:' . $item['id'] . ' 货号:' . $attr['no'] . '规格:' . $attr['attr_list'][0]['attr_name'] . "库存不足,请及时补货";
  292. $i++;
  293. }
  294. }
  295. }
  296. }
  297. $notice = $arr;
  298. //订单
  299. $order_query = Order::find()->where(['store_id' => $store_info['id'], 'is_delete' => 0, 'is_show' => 1])->andWhere(['<>', 'trade_status', '1']);
  300. //待付款
  301. $pay_order = (clone $order_query)->andWhere(['OR', ['is_pay' => Order::IS_PAY_FALSE, 'trade_status' => Order::ORDER_FLOW_DEFAULT], ['AND', ['is_pay' => Order::IS_PAY_FALSE, 'pay_type' => Order::PAY_TYPE_COD], ['<>', 'trade_status', Order::ORDER_FLOW_CANCEL]]])->count();
  302. //待发货
  303. $send_order = (clone $order_query)->andWhere(
  304. ['OR', ['trade_status' => Order::ORDER_FLOW_NO_SEND], ['is_pay' => Order::IS_PAY_FALSE, 'pay_type' => Order::PAY_TYPE_COD, 'trade_status' => Order::ORDER_FLOW_DEFAULT]]
  305. )->count();
  306. //待售后
  307. $refund_order = OrderRefund::find()->alias('or')->leftJoin(['o' => Order::tableName()], 'o.id=or.order_id');
  308. $after_sale_order = $refund_order->where([
  309. 'o.store_id' => $store_info['id'],
  310. 'or.is_delete' => Order::IS_DELETE_FALSE,
  311. 'o.is_show' => Order::IS_SHOW_TRUE,
  312. 'o.is_delete' => Order::IS_DELETE_FALSE,
  313. 'or.status' => OrderRefund::STATUS_IN
  314. ])->count();
  315. //待评价
  316. $commit_order = (clone $order_query)->andWhere(['is_comment'=>0,'trade_status'=>3])->count();
  317. //待处理
  318. $sale_order = $after_sale_order; // Todo 待售后和待处理暂时意思一样,后期优化
  319. //总加购人数
  320. $buy_count = (clone $order_query)->andWhere(['is_pay'=>1])->groupBy('user_id')->count();
  321. //昨日加购人数
  322. $yet_buy_count = (clone $order_query)->andWhere(['is_pay'=>1])->groupBy('user_id')->andWhere(['and', ['>','created_at',$yet], ['>','created_at',$td]])->count();
  323. //未结算
  324. $pay_order_money = (clone $order_query)->andWhere(['is_pay'=>0])->sum('pay_price');
  325. //昨日未结算
  326. $yet_pay_order_money = (clone $order_query)->andWhere(['is_pay'=>0])->andWhere(['and', ['>','created_at',$yet], ['>','created_at',$td]])->sum('pay_price');
  327. $store_info['end_time'] = date('Y-m-d H:i:s', $store_info['end_time']);
  328. try {
  329. $payload = \Yii::$app->jwt->getPayload();
  330. } catch (\Exception $e) {
  331. return [
  332. 'code' => 0,
  333. 'msg' => $e->getMessage(),
  334. 'status' => 401
  335. ];
  336. }
  337. $store_admin_id = $payload['store_admin_id'];
  338. if ($store_admin_id > 0) {
  339. $store_admin = \app\models\StoreAdmin::findOne($store_admin_id);
  340. $rules = !empty($store_admin->rules) ? explode(',', $store_admin->rules) : [];
  341. } else {
  342. $pickLink = AdminPickLink::LIST;
  343. if ($pickLink) {
  344. $rules = array_column($pickLink, 'key');
  345. }
  346. }
  347. if (!empty($rules)) {
  348. foreach ($rules as $rules_index => $rules_item) {
  349. if ($rules_item === 'store_pay') {
  350. unset($rules[$rules_index]);
  351. }
  352. }
  353. $rules = array_values($rules);
  354. }
  355. $storeCloud = StoreCloud::findOne(['is_delete' => 0, 'is_enable' => 1, 'store_id' => $store_info['id']]);
  356. $is_can_distribution = !empty($storeCloud->can_distribution) ? 1 : 0;// 否具备 一键铺货选品的权限
  357. $auth = [
  358. 'is_store_admin' => 1,//是否是店铺管理
  359. 'is_can_distribution' => $is_can_distribution,//是否可以选品
  360. 'is_purchase' => $storeCloud,//是否可以批发
  361. 'kefu_id' => $store_info['kefu_id']
  362. ];
  363. //实时概况
  364. $statistics_data = [];
  365. //成交订单数
  366. $pay_order_query = Order::find()->where(['store_id' => $store_info['id']])
  367. ->andWhere(['OR', ['is_pay' => 1], ['is_pay' => 0, 'pay_type' => Order::PAY_TYPE_COD]])
  368. ->andWhere(['<>', 'trade_status', 1]);
  369. $statistics_data['pay_order_count'] = (clone $pay_order_query)->select('id')->count();
  370. //成交金额
  371. $statistics_data['pay_order_price'] = (clone $pay_order_query)->select('pay_price')->sum('pay_price');
  372. //成交人数
  373. $statistics_data['pay_count'] = (clone $pay_order_query)->groupBy('user_id')
  374. ->select('user_id')->count();
  375. //成交商品数
  376. $statistics_data['pay_goods_count'] = OrderDetail::find()->alias('od')
  377. ->select('SUM(od.num)')
  378. ->leftJoin(['o' => Order::tableName()], 'od.order_id=o.id')
  379. ->where(['od.is_delete' => 0, 'o.is_delete' => 0, 'o.is_pay' => 1, 'o.store_id' => $store_info['id']])
  380. ->scalar();
  381. //成交客单价
  382. $statistics_data['pay_single_price'] = $statistics_data['pay_count'] > 0 ?
  383. bcdiv($statistics_data['pay_order_price'], $statistics_data['pay_count'], 2) :
  384. 0;
  385. //退款订单数
  386. $cancel_order_query = OrderGoodsCancel::find()
  387. ->where([
  388. 'NOT IN', 'status', [OrderGoodsCancel::STATUS_REFUSE, OrderGoodsCancel::STATUS_CANCEL]
  389. ])->andWhere(['store_id' => $store_info['id']]);
  390. $statistics_data['cancel_order_count'] = (clone $cancel_order_query)->select('id')->count();
  391. //退款金额
  392. $statistics_data['cancel_order_price'] = (clone $cancel_order_query)
  393. ->select('refund_price')->sum('refund_price');
  394. return [
  395. 'code' => 0,
  396. 'msg' => "获取成功",
  397. 'data' => [
  398. 'order' => [
  399. 'pay_order_count' => $pay_order,//待付款
  400. 'send_order_count' => $send_order,//待发货
  401. 'after_sale_order_count' => $after_sale_order,//待售后
  402. 'comment_order_count' => $commit_order,//待评价
  403. 'sale_order_count' => $sale_order //待处理
  404. ],
  405. 'notice' => $notice,
  406. 'store' => $store_info,
  407. 'total' => [
  408. 'order_num' => [//订单数
  409. 'order_count' => $order_count,
  410. 'yet_order_count' => $yet_order_count
  411. ],
  412. 'money' => [//成交额
  413. 'money_count' => $money_count,
  414. 'yet_money_count' => $yet_money_count??0
  415. ],
  416. 'visit' => [//访问量
  417. "today_visit_count" => $today_visit??0,
  418. "yet_visit_count" => $yes_visit??0
  419. ],
  420. 'browse' => [ //浏览量
  421. "today_see_count" => $today_visit??0,
  422. "yet_see_count" => $yes_visit??0
  423. ],
  424. 'buy_people' => [//加购人数
  425. "buy_count" => $buy_count??0,
  426. "yet_buy_count" => $yet_buy_count??0
  427. ],
  428. 'pay_order_money' => [//未结算
  429. "pay_order_money" => $pay_order_money??0,
  430. "yet_pay_order_money" => $yet_pay_order_money??0
  431. ]
  432. ],
  433. 'mini_qr' => $mini_qr,
  434. 'rules' => $rules,
  435. 'auth' => $auth,
  436. 'statistics_data' => $statistics_data
  437. ]
  438. ];
  439. }catch (\Exception $e){
  440. return [
  441. 'code'=>0,
  442. 'msg'=>$e->getMessage()
  443. ];
  444. }
  445. }
  446. public function getYesData()
  447. {
  448. try {
  449. $this->initWX();
  450. $store_id = $this->store_id;
  451. $timestamp = time();
  452. $lastday = [
  453. 'begin_date' => date('Ymd', strtotime("-1 day", $timestamp)),
  454. 'end_date' => date('Ymd', (strtotime("-1 day", $timestamp))),
  455. ];
  456. $yes_start_date = mktime(0,0,0,date('m'),date('d')-1,date('Y'));
  457. $yes_end_date = mktime(0,0,0,date('m'),date('d'),date('Y'))-1;
  458. //昨日访客
  459. try {
  460. $yes_visit = $this->getVisit($lastday);
  461. } catch (\Exception $e) {
  462. $yes_visit = 0;
  463. }
  464. //昨日订单数
  465. $yes_order_count = Order::find()->where(['is_delete' => 0, 'store_id' => $store_id, 'is_pay' => 1])->andWhere(['and', ['>=', 'created_at', $yes_start_date], ['<=', 'created_at', $yes_end_date]])->select('id')->count();
  466. //昨日订单支付金额
  467. $yes_order_price = Order::find()->where(['is_delete' => 0, 'store_id' => $store_id, 'is_pay' => 1])->andWhere(['and', ['>=', 'created_at', $yes_start_date], ['<=', 'created_at', $yes_end_date]])->select('total_price')->sum('total_price');
  468. //昨日经营情况
  469. $yes_data = [
  470. 'visit' => $yes_visit ?: 0,
  471. 'visit_num' => $yes_visit ?: 0,
  472. 'order_count' => $yes_order_count,
  473. 'order_price' => $yes_order_price ?: 0
  474. ];
  475. return [
  476. 'code' => 0,
  477. 'msg' => "获取成功",
  478. 'data' => $yes_data
  479. ];
  480. } catch (\Exception $e) {
  481. return [
  482. 'code'=>0,
  483. 'msg'=>$e->getMessage()
  484. ];
  485. }
  486. }
  487. public function shopData()
  488. {
  489. try {
  490. //基础数据
  491. $this->initWX();
  492. $store_id = $this->store_id;
  493. $type = (int)$this->type;
  494. $tab = (int)$this->tab;
  495. $timestamp = time();
  496. $lastday = [
  497. 'begin_date' => date('Ymd', strtotime("-1 day", $timestamp)),
  498. 'end_date' => date('Ymd', (strtotime("-1 day", $timestamp) + (60 * 60 * 24))),
  499. ];
  500. $start_date = strtotime($this->start_date);
  501. $end_date = strtotime($this->end_date);
  502. $yes_start_date = mktime(0,0,0,date('m'),date('d')-1,date('Y'));
  503. $yes_end_date = mktime(0,0,0,date('m'),date('d'),date('Y'))-1;
  504. //昨日访客
  505. try {
  506. $yes_visit = $this->getVisit($lastday);
  507. } catch (\Exception $e) {
  508. $yes_visit = 0;
  509. }
  510. //昨日订单数
  511. $yes_order_count = Order::find()->where(['is_delete' => 0, 'store_id' => $store_id])->andWhere(['and', ['>=', 'created_at', $yes_start_date], ['<=', 'created_at', $yes_end_date]])->select('id')->count();
  512. //昨日订单支付金额
  513. $yes_order_price = Order::find()->where(['is_delete' => 0, 'store_id' => $store_id])->andWhere(['and', ['>=', 'created_at', $yes_start_date], ['<=', 'created_at', $yes_end_date]])->select('total_price')->sum('total_price');
  514. //昨日经营情况
  515. $yes_data = [
  516. 'visit' => $yes_visit,
  517. 'order_count' => $yes_order_count,
  518. 'order_price' => $yes_order_price
  519. ];
  520. $time = [
  521. 'begin_date' => date("Ymd", $start_date ?: strtotime('-1 month')),
  522. 'end_date' => date("Ymd", $end_date ?: strtotime('now')),
  523. ];
  524. $table_data = [];
  525. //访问人数
  526. if ($type === 1 || ($tab === 0 && empty($type))) {
  527. $new_data = $this->getData($time);
  528. $table_data = $new_data;
  529. } else {
  530. $data_arr = $this->getDateByInterval($time['begin_date'], $time['end_date']);
  531. $new_data = $data_arr;
  532. //分享数据
  533. if ($type === 2) {
  534. foreach ($new_data as &$item) {
  535. $log = UserShareLog::find()->alias('usl')->leftJoin(['u' => User::tableName()], 'usl.parent_id = u.id')->where(['store_id' => $store_id])
  536. ->select([new Expression('count(usl.id) as value')])
  537. ->groupBy(new Expression('FROM_UNIXTIME(usl.created_at, "%Y%m%d")'))
  538. ->andWhere(['and', ['>', 'usl.created_at', strtotime($item['date'])], ['<', 'usl.created_at', (strtotime($item['date']) + (24*60*60))]])
  539. ->asArray()->one();
  540. $data = [];
  541. $data['value'] = (int)$log['value'] ?: 0;
  542. $item = array_merge($item, $data);
  543. }
  544. $table_data = $new_data;
  545. }
  546. if ($type === 3 || ($tab === 1 && empty($type))) {
  547. //商品浏览量
  548. foreach ($new_data as &$item) {
  549. $log = BrowseLog::find()->where(['store_id' => $store_id, 'is_delete' => 0])
  550. ->select([new Expression('count(id) as value')])
  551. ->groupBy(new Expression('FROM_UNIXTIME(created_at, "%Y%m%d")'))
  552. ->andWhere(['and', ['>', 'created_at', strtotime($item['date'])], ['<', 'created_at', (strtotime($item['date']) + (24*60*60))]])
  553. ->asArray()->one();
  554. $data = [];
  555. $data['value'] = (int)$log['value'] ?: 0;
  556. $item = array_merge($item, $data);
  557. }
  558. /**
  559. * 表格数据
  560. */
  561. $table_data = BrowseLog::find()->alias('bl')->leftJoin(['g' => Goods::tableName()], 'bl.log_id = g.id')
  562. ->where(['bl.store_id' => $store_id, 'bl.is_delete' => 0])
  563. ->select(['g.name', 'g.cover_pic', new Expression('count(bl.id) as value'), new Expression('FROM_UNIXTIME(bl.created_at, "%Y/%m/%d") as date')])
  564. ->groupBy([new Expression('FROM_UNIXTIME(bl.created_at, "%Y%m%d")'), 'bl.log_id'])
  565. ->andWhere(['and', ['>', 'bl.created_at', strtotime($time['begin_date'])], ['<', 'bl.created_at', (strtotime($time['end_date']) + (24*60*60))]])
  566. ->asArray()->all();
  567. }
  568. if ($type === 4) {
  569. //加购人数
  570. foreach ($new_data as &$item) {
  571. $cat_log = Cart::find()->where(['store_id' => $store_id, 'is_delete' => 0])
  572. ->select([new Expression('count(id) as value')])
  573. ->groupBy(new Expression('FROM_UNIXTIME(created_at, "%Y%m%d")'))
  574. ->andWhere(['and', ['>', 'created_at', strtotime($item['date'])], ['<', 'created_at', (strtotime($item['date']) + (24 * 60 * 60))]])
  575. ->asArray()->one();
  576. $data = [];
  577. $data['value'] = (int)$cat_log['value'] ?: 0;
  578. $item = array_merge($item, $data);
  579. }
  580. $table_data = Cart::find()->alias('c')->leftJoin(['g' => Goods::tableName()], 'c.goods_id = g.id')
  581. ->where(['c.store_id' => $store_id, 'c.is_delete' => 0])
  582. ->select(['g.name', 'g.cover_pic', new Expression('count(c.id) as value'), new Expression('FROM_UNIXTIME(c.created_at, "%Y/%m/%d") as date')])
  583. ->groupBy([new Expression('FROM_UNIXTIME(c.created_at, "%Y%m%d")'), 'c.goods_id'])
  584. ->andWhere(['and', ['>', 'c.created_at', strtotime($time['begin_date'])], ['<', 'c.created_at', (strtotime($time['end_date']) + (24*60*60))]])
  585. ->asArray()->all();
  586. }
  587. if ($type === 5 || $type === 6) {
  588. //支付人数
  589. //加购人数
  590. foreach ($new_data as &$item) {
  591. $cat_log = Order::find()->where(['store_id' => $store_id, 'is_delete' => 0, 'is_pay' => 1])
  592. ->select([new Expression('sum(total_price) as price'),new Expression('count(id) as value')])
  593. ->groupBy([new Expression('FROM_UNIXTIME(created_at, "%Y%m%d")'), 'user_id'])
  594. ->andWhere(['and', ['>', 'created_at', strtotime($item['date'])], ['<', 'created_at', (strtotime($item['date']) + (24 * 60 * 60))]])
  595. ->asArray()->one();
  596. $data = [];
  597. if ($type === 5) {
  598. $data['value'] = (int)$cat_log['value'] ?: 0;
  599. }
  600. if ($type === 6) {
  601. $data['value'] = (float)$cat_log['price'] ?: 0;
  602. }
  603. $item = array_merge($item, $data);
  604. }
  605. $table_data = OrderDetail::find()->alias('od')->leftJoin(['o' => Order::tableName()], 'od.order_id = o.od')
  606. ->leftJoin(['g' => Goods::tableName()], 'od.goods_id = g.id')->where(['o.store_id' => $store_id, 'o.is_delete' => 0, 'o.is_pay' => 1])
  607. ->select(['g.name', 'g.cover_pic', new Expression('count(od.id) as value'), new Expression('FROM_UNIXTIME(c.created_at, "%Y/%m/%d") as date')])
  608. ->groupBy([new Expression('FROM_UNIXTIME(c.created_at, "%Y%m%d")'), 'od.goods_id'])
  609. ->andWhere(['and', ['>', 'od.created_at', strtotime($time['begin_date'])], ['<', 'od.created_at', (strtotime($time['end_date']) + (24*60*60))]])
  610. ->asArray()->all();
  611. }
  612. }
  613. return [
  614. 'code' => 0,
  615. 'msg' => '获取成功',
  616. 'data' => [
  617. 'data' => $new_data,
  618. 'table_data' => $table_data
  619. ],
  620. ];
  621. } catch (\Exception $e) {
  622. return [
  623. 'code'=>0,
  624. 'msg'=>$e->getMessage()
  625. ];
  626. }
  627. }
  628. //修改商城信息
  629. public function getStoreInfo()
  630. {
  631. $t = \Yii::$app->db->beginTransaction();
  632. try {
  633. $store_id = $this->store_id;
  634. $logo = $this->logo;
  635. $name = $this->name;
  636. $coordinate = $this->coordinate;
  637. $address = $this->address;
  638. if (\Yii::$app->request->isPost) {
  639. $store = Store::findOne($store_id);
  640. if ($logo) {
  641. $store->logo = $logo;
  642. Option::set('logo', $logo, $store_id, 'store');
  643. Option::set('web_log', $logo, $store_id, 'web');
  644. }
  645. if ($name) {
  646. $store->name = $name;
  647. Option::set('name', $name, $store_id, 'store');
  648. }
  649. if ($coordinate) {
  650. $store->coordinate = $coordinate;
  651. }
  652. if ($address) {
  653. $store->address = $address;
  654. }
  655. if (!$store->save()) {
  656. throw new \Exception(json_encode($store->errors));
  657. }
  658. $t->commit();
  659. return [
  660. 'code' => 0,
  661. 'msg' => "保存成功"
  662. ];
  663. } else {
  664. $store = Store::find()->alias('s')->where(['s.id' => $store_id])
  665. ->leftJoin(['a' => Admin::tableName()], 's.admin_id = a.id')
  666. ->select('s.logo, s.name, s.coordinate, s.address, a.username')
  667. ->asArray()->one();
  668. $data = [];
  669. $data['url'] = \Yii::$app->request->getHostInfo();
  670. $store = array_merge($store, $data);
  671. return [
  672. 'code' => 0,
  673. 'msg' => '获取成功',
  674. 'data' => $store
  675. ];
  676. }
  677. } catch (\Exception $e) {
  678. $t->rollBack();
  679. return [
  680. 'code'=>0,
  681. 'msg'=>$e->getMessage()
  682. ];
  683. }
  684. }
  685. public function getVisit($time){
  686. //如果是模板方式
  687. $data = [
  688. 'begin_date' => $time['begin_date'],
  689. 'end_date' => $time['end_date']
  690. ];
  691. $mini_program = $this->wechat;
  692. if ($mini_program) {
  693. $res = $mini_program->data_cube->summaryTrend($data['begin_date'], $data['end_date']);
  694. return $res['list'][0]['visit_total']; //返回访问人数
  695. } else {
  696. return 0;
  697. }
  698. }
  699. public function getData($time)
  700. {
  701. try {
  702. $store_id = $this->store_id;
  703. $data = [
  704. 'begin_date' => $time['begin_date'],
  705. 'end_date' => $time['end_date']
  706. ];
  707. $data_arr = $this->getDateByInterval($data['begin_date'], $data['end_date']);
  708. $mini_program = $this->wechat;
  709. if ($mini_program) {
  710. foreach ($data_arr as &$item) {
  711. $res = $mini_program->data_cube->dailyVisitTrend(date('Ymd', strtotime($item['date'])), date('Ymd', strtotime($item['date'])));
  712. if (isset($res['list'][0]['visit_pv'])) {
  713. $item['value'] = $res['list'][0]['visit_pv'];
  714. }
  715. }
  716. } else {
  717. $data_arr = [];
  718. }
  719. return $data_arr;
  720. } catch (\Exception $e) {
  721. return [
  722. 'code' => 1,
  723. 'msg' => $e->getMessage()
  724. ];
  725. }
  726. }
  727. public function getDateByInterval(string $st, string $et, string $format = 'Y/m/d') :array
  728. {
  729. //日期格式不正确
  730. if (strtotime($st) > strtotime($et)) return [];
  731. $returnData = [];
  732. $i = 0;
  733. do {
  734. $temp = [];
  735. $tempDate = date('Y/m/d', strtotime('+' . $i . ' day', strtotime($st)));
  736. // $temp['name'] = date('Y-m-d', strtotime('+' . $i . ' day', strtotime($st)));
  737. // $temp['startDate'] = date('Y-m-d', strtotime('+' . $i . ' day', strtotime($st)));
  738. // $temp['endDate'] = date('Y-m-d', strtotime('+' . $i . ' day', strtotime($st)));
  739. $temp['date'] = date($format, strtotime('+' . $i . ' day', strtotime($st)));
  740. $returnData[] = $temp;
  741. $i++;
  742. } while (strtotime($tempDate) < strtotime($et));
  743. return $returnData;
  744. }
  745. public function isPay($order_id){
  746. $order = StoreReOrder::findOne($order_id);
  747. if($order->is_pay == 1){
  748. // $store = Store::findOne($order->store_id);
  749. // $store->end_time = strtotime('+1 year');
  750. // $store->save();
  751. return [
  752. 'code'=>0,
  753. 'msg'=>"支付成功"
  754. ];
  755. }
  756. }
  757. public function storeSetting() {
  758. try {
  759. $store_id = $this->store_id;
  760. $store = Store::findOne($store_id);
  761. if (!$store) {
  762. throw new \Exception('商城信息错误');
  763. }
  764. if (\Yii::$app->request->isPost) {
  765. $rate = $this->rate;
  766. // $is_auth_trans = $this->is_auth_trans;
  767. $cloud_is_update = $this->cloud_is_update;
  768. $store->rate = $rate;
  769. // $store->is_auth_trans = $is_auth_trans;
  770. Option::set('cloud_is_update', $cloud_is_update, $store_id, 'store');
  771. if (!$store->save()) {
  772. throw new \Exception(json_encode($store->errors));
  773. }
  774. return [
  775. 'code' => 0,
  776. 'msg' => 'success'
  777. ];
  778. } else {
  779. $cloud_is_update = Option::get('cloud_is_update', $store_id, 'store', 0)['value'];
  780. return [
  781. 'code' => 0,
  782. 'msg' => 'success',
  783. 'data' => [
  784. 'rate' => $store->rate ?: '0.00',
  785. // 'is_auth_trans' => $store->is_auth_trans ?: 0,
  786. 'cloud_is_update' => (int)$cloud_is_update
  787. ]
  788. ];
  789. }
  790. } catch (\Exception $e) {
  791. return [
  792. 'code' => 1,
  793. 'msg' => $e->getMessage()
  794. ];
  795. }
  796. }
  797. }