System.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. <?php
  2. namespace app\admin\controller\store;
  3. use app\common\controller\AdminController;
  4. use app\http\IResponse;
  5. use Lettered\Support\Upload;
  6. use PhpOffice\PhpSpreadsheet\Cell\DataType;
  7. use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
  8. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  9. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  10. use think\Db;
  11. class System extends AdminController
  12. {
  13. /**
  14. * 数据统计
  15. *
  16. * @author 许祖兴 < zuxing.xu@lettered.cn>
  17. * @date 2020/7/17 11:34
  18. *
  19. * @return mixed
  20. * @throws \think\db\exception\DataNotFoundException
  21. * @throws \think\db\exception\ModelNotFoundException
  22. * @throws \think\exception\DbException
  23. */
  24. public function getAgentStat()
  25. {
  26. // 接收数据
  27. $where = [];
  28. //组合搜索
  29. !empty(input('areaId')) && $where[]
  30. = ['area_id', 'eq', input('areaId')];
  31. // 时间处理
  32. if (!empty(input('time'))){
  33. list($start, $end) = str2arr(trim(input('time')),'-');
  34. $where[] = ['created_at', 'between', [strtotime($start), strtotime($end)]];
  35. }
  36. // 消费总额包含 商品、接单、技能、摩的
  37. // 直接读取支付记录表吧
  38. $coun = [
  39. 'total' => model('common/OrderPaylog')->sum('pay_price'),
  40. 'days' => model('common/OrderPaylog')->whereTime('created_at','d')->sum('pay_price'),
  41. 'month' => model('common/OrderPaylog')->whereTime('created_at','m')->sum('pay_price'),
  42. 'year' => model('common/OrderPaylog')->whereTime('created_at','y')->sum('pay_price')
  43. ];
  44. // 商品订单统计
  45. // 摩的订单统计
  46. // 配送订单统计
  47. // 技能订单统计
  48. $sdata = [
  49. 'goods' => [
  50. 'total' => db('goods_order')->where($where)->count(),
  51. 'days' => db('goods_order')->whereTime('created_at','d')->where($where)->count(),
  52. 'month' => db('goods_order')->whereTime('created_at','m')->where($where)->count(),
  53. 'year' => db('goods_order')->whereTime('created_at','y')->where($where)->count(),
  54. ],
  55. 'motor' => [
  56. 'total' => db('taxi_order')->where($where)->count(),
  57. 'days' => db('taxi_order')->whereTime('created_at','d')->where($where)->count(),
  58. 'month' => db('taxi_order')->whereTime('created_at','m')->where($where)->count(),
  59. 'year' => db('taxi_order')->whereTime('created_at','y')->where($where)->count(),
  60. ],
  61. 'skill' => [
  62. 'total' => db('skill_order')->where($where)->count(),
  63. 'days' => db('skill_order')->whereTime('created_at','d')->where($where)->count(),
  64. 'month' => db('skill_order')->whereTime('created_at','m')->where($where)->count(),
  65. 'year' => db('skill_order')->whereTime('created_at','y')->where($where)->count(),
  66. ],
  67. 'mission' => [
  68. 'total' => db('mission_order')->where($where)->count(),
  69. 'days' => db('mission_order')->whereTime('created_at','d')->where($where)->count(),
  70. 'month' => db('mission_order')->whereTime('created_at','m')->where($where)->count(),
  71. 'year' => db('mission_order')->whereTime('created_at','y')->where($where)->count(),
  72. ]
  73. ];
  74. // 统计
  75. $order = [ 'total' => 0, 'days' => 0, 'month' => 0, 'year' => 0, ];
  76. foreach ($sdata as $item){
  77. $order['total'] += $item['total'];
  78. $order['days'] += $item['days'];
  79. $order['month'] += $item['month'];
  80. $order['year'] += $item['year'];
  81. }
  82. $data['order'] = $order;
  83. // 用户 ->where('deleted_at','=','0') 不包含删除
  84. $user = [
  85. 'total' => db('users')->where('deleted_at','=','0')->count(),
  86. 'days' => db('users')->whereTime('created_at','d')->where('deleted_at','=','0')->count(),
  87. 'month' => db('users')->whereTime('created_at','m')->where('deleted_at','=','0')->count(),
  88. 'year' => db('users')->whereTime('created_at','y')->where('deleted_at','=','0')->count()
  89. ];
  90. $data['user'] = $user;
  91. // 统计图
  92. $res = [];
  93. for ($month = 1; $month <=12 ; $month ++){
  94. $res[] = model('common/GoodsOrder')
  95. ->where($where)
  96. ->whereTime('created_at', 'between', $this->getMonthTime($month))
  97. ->count();;
  98. }
  99. $data['coun'] = $coun;
  100. $data['chart'] = $res;
  101. return IResponse::success($data,"加载数据成功");
  102. }
  103. private function getMonthTime($month)
  104. {
  105. //
  106. $firstday = date('Y-m-01', strtotime(date('Y') . '-' . $month . '-1'));
  107. $lastday = date('Y-m-d', strtotime("$firstday +1 month -1 day"));
  108. return array($firstday,$lastday);
  109. }
  110. /**
  111. *导出
  112. *
  113. * @author 许祖兴 < zuxing.xu@lettered.cn>
  114. * @date 2020/7/17 12:51
  115. *
  116. * @return mixed
  117. * @throws \think\db\exception\DataNotFoundException
  118. * @throws \think\db\exception\ModelNotFoundException
  119. * @throws \think\exception\DbException
  120. */
  121. public function exportDataSheet()
  122. {
  123. $param = $this->request->param();
  124. $valid = $this->validate($param,[
  125. 'model| 导出数据' => 'require'
  126. ]);
  127. // 错误返回
  128. (true !== $valid) && IResponse::failure($valid);
  129. // 一些条件
  130. $where = [];
  131. // 时间处理
  132. if (!empty(input('created_at'))){
  133. list($start, $end) = str2arr(input('created_at'),'-');
  134. $where[] = ['created_at', 'between', [strtotime($start), strtotime($end)]];
  135. }
  136. switch ($param['model']){
  137. case "users":
  138. $this->exportUserSheet($where);
  139. break;
  140. case "seller":
  141. $this->exportSellerSheet($where);
  142. break;
  143. case "order":
  144. $this->exportOrderSheet($where);
  145. break;
  146. }
  147. return IResponse::failure("数据异常");
  148. }
  149. /**
  150. * 导出会员数据
  151. *
  152. * @author 许祖兴 < zuxing.xu@lettered.cn>
  153. * @date 2020/7/17 12:04
  154. *
  155. * @param $where
  156. * @throws \think\db\exception\DataNotFoundException
  157. * @throws \think\db\exception\ModelNotFoundException
  158. * @throws \think\exception\DbException
  159. */
  160. private function exportUserSheet($where)
  161. {
  162. $list = db('users')->where($where)->select();
  163. // 是否空数据
  164. if (!$list){
  165. IResponse::failure("查找不到数据");
  166. }
  167. foreach ($list as $key => &$item) {
  168. // 类型处理
  169. $item['gender'] = $item['gender'] > 0 ? "男" : "女";
  170. $item['is_seller'] = $item['is_seller'] > 0 ? "是" : "否";
  171. $item['is_agent'] = $item['is_agent'] == 2 ? "是" : "否";
  172. $item['is_verify'] = $item['is_verify'] == 2 ? "已实名" : "未实名";
  173. $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
  174. $item['status'] = $item['status'] >= 1 ? '正常' : '锁定';
  175. }
  176. $head = ['会员号', 'OpenID', '会员昵称', '联系方式', '余额', '资产', '是否卖家', '是否代理', '是否实名', '注册时间'];// 表头信息
  177. $keys = ['card_id', 'open_id', 'nickname', 'mobile', 'balance', 'property', 'is_seller', 'is_agent', 'is_verify', 'created_at'];
  178. $this->downloadExcel("会员记录" . date("YmdHis", time()), $list, $head, $keys);
  179. }
  180. /**
  181. * 导出商户数据
  182. *
  183. * @author 许祖兴 < zuxing.xu@lettered.cn>
  184. * @date 2020/7/17 12:49
  185. *
  186. * @param $where
  187. * @throws \think\db\exception\DataNotFoundException
  188. * @throws \think\db\exception\ModelNotFoundException
  189. * @throws \think\exception\DbException
  190. */
  191. private function exportSellerSheet($where)
  192. {
  193. $list = db('seller')->where($where)->select();
  194. // 是否空数据
  195. if (!$list){
  196. IResponse::failure("查找不到数据");
  197. }
  198. foreach ($list as $key => &$item) {
  199. // 类型处理
  200. $item['is_allow'] = $item['is_allow'] == 2 ? "通过" : $item['is_allow'] == 2 ? "待审核" : "未提交";
  201. // 地址拼接
  202. $item['address'] = $item['province'] . $item['city'] . $item['country'] .$item['address'];
  203. $item['fd_img'] = dejson($item['fd_img']);
  204. $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
  205. $item['status'] = $item['status'] >= 1 ? '正常' : '锁定';
  206. }
  207. // halt($list);
  208. $head = ['店铺名称', '店铺地址','主营产品','店铺照片','经度', '维度', '联系人', '联系方式', '身份证', '店铺审核', '备注信息', '注册时间'];// 表头信息
  209. $keys = ['seller_name', 'address','products','fd_img', 'lng','lat', 'contact', 'mobile', 'id_card', 'is_allow','remark', 'created_at'];
  210. $this->downloadExcel("店铺记录" . date("YmdHis", time()), $list, $head, $keys);
  211. }
  212. /**
  213. *
  214. * @author 许祖兴 < zuxing.xu@lettered.cn>
  215. * @date 2020/7/17 10:52
  216. *
  217. * @param array $where
  218. *
  219. * @throws \think\db\exception\DataNotFoundException
  220. * @throws \think\db\exception\ModelNotFoundException
  221. * @throws \think\exception\DbException
  222. */
  223. private function exportOrderSheet($where)
  224. {
  225. //TODO 可以加一些时间查询,地区查询等
  226. $list = db('goods_order')->alias('g')
  227. ->join('ins_users u','u.id = g.user_id')
  228. ->join('ins_seller s','s.id = g.seller_id')
  229. ->join('ins_users_addr d','d.id = g.addr_id')
  230. ->join('ins_china c','c.id = g.area_id')
  231. ->field('g.*,u.nickname,s.seller_name,c.name as area_name,d.name,d.mobile,d.province,d.city,d.country,d.detail')
  232. ->select();
  233. foreach ($list as $key => &$item){
  234. // 类型处理
  235. $item['is_pin'] = $item['is_pin'] > 0 ? "是" : "否";
  236. $item['pin_rebate_rec'] = $item['pin_rebate_rec'] > 0 ? "已领取" : "未领取";
  237. // 地址拼接
  238. $item['address'] = $item['province'] . $item['city'] . $item['country'] .$item['detail'] . "(" . $item['name'] . $item['mobile'] . ")" ;
  239. // 时间处理
  240. $item['pin_rebate_expired'] = $item['pin_rebate_expired'] > 0 ? date('Y-m-d H:i:s',$item['pin_rebate_expired']) : 'NULL';
  241. $item['paid_at'] = $item['paid_at'] > 0 ? date('Y-m-d H:i:s',$item['paid_at']) : 'NULL';
  242. $item['refund_at'] = $item['refund_at'] > 0 ? date('Y-m-d H:i:s',$item['refund_at']) : 'NULL';
  243. $item['shipping_at'] = $item['paid_at'] > 0 ? date('Y-m-d H:i:s',$item['shipping_at']) : 'NULL';
  244. $item['received_at'] = $item['paid_at'] > 0 ? date('Y-m-d H:i:s',$item['received_at']) : 'NULL';
  245. $item['created_at'] = date('Y-m-d H:i:s',$item['created_at']);
  246. // 订单状态
  247. // 0: 已关闭 1:待支付, 2:待发货,3:待收货 , 4: 已完成 , 5: 待开团 , 6: 未中团
  248. $status = "已关闭";
  249. switch ($item['status']) {
  250. case 1 :
  251. $status = "待支付";
  252. break;
  253. case 2 :
  254. $status = "待发货";
  255. break;
  256. case 3 :
  257. $status = "待收货";
  258. break;
  259. case 4 :
  260. $status = "已完成";
  261. break;
  262. case 5 :
  263. $status = "待开团";
  264. break;
  265. case 6 :
  266. $status = "未中团";
  267. break;
  268. }
  269. $item['status'] = $status;
  270. }
  271. $head = ['订单号','区域号', '区域名称','经营店铺', '下单用户', '收获地址', '订单金额', '付款金额', '是否拼团', '是否拼团','返现金额领取', '拼团返现过期时间', '付款时间','退款时间', '发货时间', '收货时间', '下单时间', '订单状态'];// 表头信息
  272. $keys = ['order_no','area_id','area_name', 'seller_name', 'nickname','address', 'total_price', 'pay_price', 'is_pin', 'pin_rebate_rec', 'pin_rebate', 'pin_rebate_expired', 'paid_at', 'refund_at', 'shipping_at', 'received_at', 'created_at', 'status'];
  273. $this->downloadExcel("订单记录" . date("YmdHis", time()), $list, $head, $keys);
  274. }
  275. //报表导出核心方法
  276. //* 导出excel表
  277. //* $data:要导出excel表的数据,接受一个二维数组
  278. //* $name:excel表的表名
  279. //* $head:excel表的表头,接受一个一维数组
  280. //* $key:$data中对应表头的键的数组,接受一个一维数组
  281. //* 备注:此函数缺点是,表头(对应列数)不能超过26;
  282. //*循环不够灵活,一个单元格中不方便存放两个数据库字段的值
  283. public function downloadExcel($name = '表名称', $data = [], $head = [], $keys = [])
  284. {
  285. $count = count($head); //计算表头数量
  286. $spreadsheet = new Spreadsheet();
  287. $sheet = $spreadsheet->getActiveSheet();
  288. for ($i = 65; $i < $count + 65; $i++) { //数字转字母从65开始,循环设置表头:
  289. $sheet->setCellValue(strtoupper(chr($i)) . '1', $head[$i - 65]);
  290. }
  291. foreach ($data as $key => $item) { //循环设置单元格:
  292. //$key+2,因为第一行是表头,所以写到表格时 从第二行开始写
  293. for ($i = 65; $i < $count + 65; $i++) { //数字转字母从65开始:
  294. if ($i == 65) {
  295. $sheet->setCellValueExplicit(strtoupper(chr($i)) . ($key + 2), $item[$keys[$i - 65]], DataType::TYPE_STRING);
  296. }elseif (is_array($item[$keys[$i - 65]])){
  297. $sheet->setCellValue(strtoupper(chr($i)) . ($key + 2), arr2str($item[$keys[$i - 65]]));
  298. // foreach ($item[$keys[$i - 65]] as $ki){
  299. // $drawing[$key + 2] = new Drawing();
  300. // $drawing[$key + 2]->setName('Logo');
  301. // $drawing[$key + 2]->setDescription('Logo');
  302. // $drawing[$key + 2]->setPath($this->app->getRootPath() . 'public' . filter_annex_url($ki));
  303. // $drawing[$key + 2]->setWidth(80);
  304. // $drawing[$key + 2]->setHeight(80);
  305. // $drawing[$key + 2]->setCoordinates(strtoupper(chr($i)) . ($key + 2));
  306. // $drawing[$key + 2]->setWorksheet($spreadsheet->getActiveSheet());
  307. // }
  308. }
  309. else
  310. $sheet->setCellValue(strtoupper(chr($i)) . ($key + 2), $item[$keys[$i - 65]]);
  311. $spreadsheet->getActiveSheet()->getColumnDimension(strtoupper(chr($i)))->setWidth(30); //固定列宽
  312. }
  313. }
  314. // 全局行高
  315. // $spreadsheet->getActiveSheet()->getDefaultRowDimension()->setRowHeight(100);
  316. $writer = new Xlsx($spreadsheet);
  317. $path = $this->app->getRootPath(). '/public/uploads/export/';
  318. //
  319. if(!is_dir($path)){
  320. mkdir($path, 0755);
  321. }
  322. // 保存到文件
  323. $writer->save( $path . $name .'.xlsx');
  324. //删除清空:
  325. $spreadsheet->disconnectWorksheets();
  326. return IResponse::success([
  327. 'url' => get_annex_url('/export/' . $name .'.xlsx')
  328. ],"导出数据成功");
  329. }
  330. /**
  331. * 关于我们
  332. *
  333. * @author 许祖兴 < zuxing.xu@lettered.cn>
  334. * @date 2020/7/7 11:43
  335. *
  336. * @return mixed
  337. */
  338. public function about()
  339. {
  340. if ($this->request->isPost()){
  341. // 接收数据
  342. $params = $this->request->param();
  343. // 校验
  344. $valid = $this->validate($params, [
  345. 'content|内容数据' => 'require'
  346. ]);
  347. (true !== $valid) && IResponse::failure($valid);
  348. // base64encode
  349. // $params['content'] = base64_encode($params['content']);
  350. // 更新数据
  351. model('common/SystemConfig')->update([
  352. 'value' => $params['content']
  353. ],['name' => 'about','group' => 'store']);
  354. return IResponse::success("更新成功");
  355. }
  356. return IResponse::success([
  357. 'content' => sys_config('about','store')
  358. ]);
  359. }
  360. }