Common.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\adminapi\controller;
  12. use app\services\system\config\SystemConfigServices;
  13. use app\services\system\SystemAuthServices;
  14. use app\services\order\StoreOrderServices;
  15. use app\services\product\product\StoreProductServices;
  16. use app\services\product\product\StoreProductReplyServices;
  17. use app\services\user\UserExtractServices;
  18. use app\services\product\sku\StoreProductAttrValueServices;
  19. use app\services\system\SystemMenusServices;
  20. use app\services\user\UserServices;
  21. use crmeb\services\HttpService;
  22. /**
  23. * 公共接口基类 主要存放公共接口
  24. * Class Common
  25. * @package app\adminapi\controller
  26. */
  27. class Common extends AuthController
  28. {
  29. /**
  30. * 获取logo
  31. * @return mixed
  32. */
  33. public function getLogo()
  34. {
  35. return app('json')->success([
  36. 'logo' => sys_config('site_logo'),
  37. 'logo_square' => sys_config('site_logo_square')
  38. ]);
  39. }
  40. /**
  41. * @return mixed
  42. */
  43. public function check_auth()
  44. {
  45. try {
  46. [$res, $installtime, $encryptStr] = $this->authorizationDecryptCrmeb();
  47. if ($installtime) {
  48. if (!isset($res['id']) || !$res['id']) {
  49. return app('json')->fail('您暂未取得授权,请及时前往CRMEB官方进行授权', ['auth' => false]);
  50. } else if (isset($res['id']) && $res['id'] == -1) {
  51. $time = $installtime + (30 * 3600 * 24);
  52. if ($time < time()) {
  53. return app('json')->success('您的授权已过期请及时前往CRMEB官方进行授权', ['auth' => false]);
  54. } else {
  55. $nowTime = ($time - time()) / (3600 * 24);
  56. return app('json')->success('您得授权证书还有' . (int)$nowTime . '天过期,请及时前往CRMEB官方进行授权认证!', ['auth' => true]);
  57. }
  58. } else {
  59. return app('json')->success('succes', ['auth' => true]);
  60. }
  61. } else {
  62. return app('json')->fail('授权文件读取错误');
  63. }
  64. } catch (\RuntimeException $e) {
  65. return app('json')->fail($e->getMessage());
  66. }
  67. }
  68. /**
  69. * @return mixed
  70. */
  71. public function auth()
  72. {
  73. [$res, $installtime, $encryptStr] = $this->authorizationDecryptCrmeb();
  74. $version = get_crmeb_version();
  75. $res = HttpService::request('http://authorize.crmeb.net/api/auth_cert_query', 'post', [
  76. 'domain_name' => $this->request->host(),
  77. 'label' => 23,
  78. 'version' => $version
  79. ]);
  80. $res = $res ? json_decode($res, true) : [];
  81. $status = $res['data']['status'] ?? -9;
  82. $time = $installtime + (30 * 3600 * 24);
  83. if ($time < time()) {
  84. $day = 0;
  85. } else {
  86. $day = (int)bcdiv((string)($time - time()), (string)(3600 * 24), 0);
  87. }
  88. $defaultRecordCode = '00000000';
  89. switch ((int)$status) {
  90. case 1:
  91. //审核成功
  92. $authCode = $res['data']['auth_code'] ?? $defaultRecordCode;
  93. $autoContent = $res['data']['auto_content'] ?? '';
  94. try {
  95. /** @var SystemConfigServices $services */
  96. $services = app()->make(SystemConfigServices::class);
  97. if ($services->count(['menu_name' => 'cert_crmeb'])) {
  98. $services->update(['menu_name' => 'cert_crmeb'], ['value' => json_encode($autoContent . ',' . $authCode)]);
  99. } else {
  100. $services->save([
  101. 'menu_name' => 'cert_crmeb',
  102. 'type' => 'text',
  103. 'input_type' => 'input',
  104. 'config_tab_id' => 1,
  105. 'value' => json_encode($autoContent . ',' . $authCode),
  106. 'status' => 2,
  107. 'info' => '授权密钥'
  108. ]);
  109. }
  110. } catch (\Throwable $e) {
  111. return app('json')->fail('授权成功,写入数据库失败,请检查数据库链接配置');
  112. }
  113. return app('json')->success(['status' => 1, 'authCode' => $authCode, 'day' => 0]);
  114. break;
  115. case 2:
  116. //审核失败
  117. return app('json')->success(['status' => 2, 'day' => $day]);
  118. break;
  119. case -1:
  120. //没有提交
  121. return app('json')->success(['status' => -1, 'day' => $day]);
  122. break;
  123. case 0:
  124. //待审核
  125. return app('json')->success(['status' => 0, 'day' => $day]);
  126. break;
  127. default:
  128. return app('json')->success(['status' => -9, 'day' => $day]);
  129. break;
  130. }
  131. }
  132. /**
  133. * 申请授权
  134. * @return mixed
  135. */
  136. public function auth_apply(SystemAuthServices $services)
  137. {
  138. $version = get_crmeb_version();
  139. $data = $this->request->postMore([
  140. ['company_name', ''],
  141. ['domain_name', ''],
  142. ['order_id', ''],
  143. ['phone', ''],
  144. ['label', 1],
  145. ['captcha', ''],
  146. ]);
  147. if (!$data['company_name']) {
  148. return app('json')->fail('请填写公司名称');
  149. }
  150. if (!$data['domain_name']) {
  151. return app('json')->fail('请填写授权域名');
  152. }
  153. if (!$data['phone']) {
  154. return app('json')->fail('请填写手机号码');
  155. }
  156. if (!$data['order_id']) {
  157. return app('json')->fail('请填写订单id');
  158. }
  159. if (!$data['captcha']) {
  160. return app('json')->fail('请填写验证码');
  161. }
  162. $datas = explode('.', $data['domain_name']);
  163. $n = count($datas);
  164. $preg = '/[\w].+\.(com|net|org|gov|edu)\.cn$/';
  165. if(($n > 2) && preg_match($preg,$data['domain_name'])){
  166. //双后缀取后3位
  167. $domain_name = $datas[$n-3].'.'.$datas[$n-2].'.'.$datas[$n-1];
  168. }else{
  169. //非双后缀取后两位
  170. $domain_name = $datas[$n-2].'.'.$datas[$n-1];
  171. }
  172. $data['domain_name'] = $domain_name;
  173. $services->authApply($data);
  174. return app('json')->success("申请授权成功!");
  175. }
  176. /**
  177. * 首页头部统计数据
  178. * @return mixed
  179. */
  180. public function homeStatics()
  181. {
  182. /** @var StoreOrderServices $orderServices */
  183. $orderServices = app()->make(StoreOrderServices::class);
  184. $info = $orderServices->homeStatics();
  185. return app('json')->success(compact('info'));
  186. }
  187. //增长率
  188. public function growth($nowValue, $lastValue)
  189. {
  190. if ($lastValue == 0 && $nowValue == 0) return 0;
  191. if ($lastValue == 0) return round($nowValue, 2);
  192. if ($nowValue == 0) return -round($lastValue, 2);
  193. return bcmul(bcdiv((bcsub($nowValue, $lastValue, 2)), $lastValue, 2), 100, 2);
  194. }
  195. /**
  196. * 订单图表
  197. */
  198. public function orderChart()
  199. {
  200. $cycle = $this->request->param('cycle') ?: 'thirtyday';//默认30天
  201. /** @var StoreOrderServices $orderServices */
  202. $orderServices = app()->make(StoreOrderServices::class);
  203. $chartdata = $orderServices->orderCharts($cycle);
  204. return app('json')->success($chartdata);
  205. }
  206. /**
  207. * 用户图表
  208. */
  209. public function userChart()
  210. {
  211. /** @var UserServices $uServices */
  212. $uServices = app()->make(UserServices::class);
  213. $chartdata = $uServices->userChart();
  214. return app('json')->success($chartdata);
  215. }
  216. /**
  217. * 交易额排行
  218. * @return mixed
  219. */
  220. public function purchaseRanking()
  221. {
  222. /** @var StoreProductAttrValueServices $valueServices */
  223. $valueServices = app()->make(StoreProductAttrValueServices::class);
  224. $list = $valueServices->purchaseRanking();
  225. return app('json')->success(compact('list'));
  226. }
  227. /**
  228. * 待办事统计
  229. * @return mixed
  230. */
  231. public function jnotice()
  232. {
  233. /** @var StoreOrderServices $orderServices */
  234. $orderServices = app()->make(StoreOrderServices::class);
  235. $data['ordernum'] = $orderServices->storeOrderCount();
  236. $store_stock = sys_config('store_stock');
  237. if ($store_stock < 0) $store_stock = 2;
  238. /** @var StoreProductServices $storeServices */
  239. $storeServices = app()->make(StoreProductServices::class);
  240. $data['inventory'] = $storeServices->count(['type' => 5, 'store_stock' => $store_stock]);//警戒库存
  241. /** @var StoreProductReplyServices $replyServices */
  242. $replyServices = app()->make(StoreProductReplyServices::class);
  243. $data['commentnum'] = $replyServices->replyCount();
  244. /** @var UserExtractServices $extractServices */
  245. $extractServices = app()->make(UserExtractServices::class);
  246. $data['reflectnum'] = $extractServices->userExtractCount();//提现
  247. $data['msgcount'] = intval($data['ordernum']) + intval($data['inventory']) + intval($data['commentnum']) + intval($data['reflectnum']);
  248. $data['newOrderId'] = $orderServices->newOrderId(1);
  249. if (count($data['newOrderId'])) $orderServices->newOrderUpdate($data['newOrderId']);
  250. $value = [];
  251. if ($data['ordernum'] != 0) {
  252. $value[] = [
  253. 'title' => "您有$data[ordernum]个待发货的订单",
  254. 'type' => 'bulb',
  255. 'url' => '/admin/order/list?status=1'
  256. ];
  257. }
  258. if ($data['inventory'] != 0) {
  259. $value[] = [
  260. 'title' => "您有$data[inventory]个商品库存预警",
  261. 'type' => 'information',
  262. 'url' => '/admin/product/product_list?type=5',
  263. ];
  264. }
  265. if ($data['commentnum'] != 0) {
  266. $value[] = [
  267. 'title' => "您有$data[commentnum]条评论待回复",
  268. 'type' => 'bulb',
  269. 'url' => '/admin/product/product_reply?is_reply=0'
  270. ];
  271. }
  272. if ($data['reflectnum'] != 0) {
  273. $value[] = [
  274. 'title' => "您有$data[reflectnum]个提现申请待审核",
  275. 'type' => 'bulb',
  276. 'url' => '/admin/finance/user_extract/index?status=0',
  277. ];
  278. }
  279. return app('json')->success($this->noticeData($value));
  280. }
  281. /**
  282. * 消息返回格式
  283. * @param array $data
  284. * @return array
  285. */
  286. public function noticeData(array $data): array
  287. {
  288. // 消息图标
  289. $iconColor = [
  290. // 邮件 消息
  291. 'mail' => [
  292. 'icon' => 'md-mail',
  293. 'color' => '#3391e5'
  294. ],
  295. // 普通 消息
  296. 'bulb' => [
  297. 'icon' => 'md-bulb',
  298. 'color' => '#87d068'
  299. ],
  300. // 警告 消息
  301. 'information' => [
  302. 'icon' => 'md-information',
  303. 'color' => '#fe5c57'
  304. ],
  305. // 关注 消息
  306. 'star' => [
  307. 'icon' => 'md-star',
  308. 'color' => '#ff9900'
  309. ],
  310. // 申请 消息
  311. 'people' => [
  312. 'icon' => 'md-people',
  313. 'color' => '#f06292'
  314. ],
  315. ];
  316. // 消息类型
  317. $type = array_keys($iconColor);
  318. // 默认数据格式
  319. $default = [
  320. 'icon' => 'md-bulb',
  321. 'iconColor' => '#87d068',
  322. 'title' => '',
  323. 'url' => '',
  324. 'type' => 'bulb',
  325. 'read' => 0,
  326. 'time' => 0
  327. ];
  328. $value = [];
  329. foreach ($data as $item) {
  330. $val = array_merge($default, $item);
  331. if (isset($item['type']) && in_array($item['type'], $type)) {
  332. $val['type'] = $item['type'];
  333. $val['iconColor'] = $iconColor[$item['type']]['color'] ?? '';
  334. $val['icon'] = $iconColor[$item['type']]['icon'] ?? '';
  335. }
  336. $value[] = $val;
  337. }
  338. return $value;
  339. }
  340. /**
  341. * 格式化菜单
  342. * @return mixed
  343. * @throws \think\db\exception\DataNotFoundException
  344. * @throws \think\db\exception\DbException
  345. * @throws \think\db\exception\ModelNotFoundException
  346. */
  347. public function menusList()
  348. {
  349. /** @var SystemMenusServices $menusServices */
  350. $menusServices = app()->make(SystemMenusServices::class);
  351. $list = $menusServices->getSearchList();
  352. $counts = $menusServices->getColumn([
  353. ['is_show', '=', 1],
  354. ['auth_type', '=', 1],
  355. ['is_del', '=', 0],
  356. ['is_show_path', '=', 0],
  357. ], 'pid');
  358. $data = [];
  359. foreach ($list as $key => $item) {
  360. $pid = $item->getData('pid');
  361. $data[$key] = json_decode($item, true);
  362. $data[$key]['pid'] = $pid;
  363. if (in_array($item->id, $counts)) {
  364. $data[$key]['type'] = 1;
  365. } else {
  366. $data[$key]['type'] = 0;
  367. }
  368. }
  369. return app('json')->success(sort_list_tier($data));
  370. }
  371. /**
  372. * @param bool $bool
  373. * @param callable|null $callable
  374. * @return array|bool
  375. */
  376. protected function authorizationDecryptCrmeb()
  377. {
  378. $path = app()->getRootPath() . 'public' . DS . 'install' . DS . 'install.lock';
  379. if (!is_file($path)) {
  380. $path = app()->getRootPath() . ".constant";
  381. }
  382. if (!is_file($path)) {
  383. throw new \RuntimeException('授权文件丢失', 42010);
  384. }
  385. $installtime = (int)@filectime($path);
  386. $time = $installtime;
  387. if (!$time) {
  388. $time = time() - 10;
  389. }
  390. if (date('m', $time) < date('m', time())) {
  391. $time = time() - 10;
  392. }
  393. $encryptStr = app()->db->name('system_config')->where('menu_name', 'cert_crmeb')->value('value');
  394. $encryptStr = $encryptStr ? json_decode($encryptStr, true) : null;
  395. $res = ['id' => '-1', 'key' => 'crmeb'];
  396. $host = request()->host(true);
  397. $data = explode('.', $host);
  398. $n = count($data);
  399. $preg = '/[\w].+\.(com|net|org|gov|edu)\.cn$/';
  400. if(($n > 2) && preg_match($preg,$host)){
  401. //双后缀取后3位
  402. $url = $data[$n-3].'.'.$data[$n-2].'.'.$data[$n-1];
  403. }else{
  404. //非双后缀取后两位
  405. $url = $data[$n-2].'.'.$data[$n-1];
  406. }
  407. if (in_array(date('d'), [5, 10, 15, 20, 25, 30]) && rand(1000, 100000) < 4000 && $encryptStr && $time < time()) {
  408. $res = HttpService::request('http://store.crmeb.net/api/web/auth/get_id', 'POST', [
  409. 'domain_name' => $url,
  410. 'label' => 1,
  411. ]);
  412. if (!isset($res['id']) || !$res['id']) {
  413. $res = json_decode($res, true);
  414. if (!$res['data']['id'] && $encryptStr) {
  415. app()->db->name('system_config')->where('menu_name', 'cert_crmeb')->delete();
  416. throw new \Exception('您的授权已到期,请联系CRMEB官方进行授权认证');
  417. }
  418. }
  419. file_put_contents($path, time() + 86400);
  420. $installtime = $installtime + 86400;
  421. }
  422. return [$res, $installtime, $encryptStr];
  423. }
  424. }