ExcelService.php 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace crmeb\services;
  12. use app\common\repositories\store\order\StoreImportDeliveryRepository;
  13. use app\common\repositories\store\order\StoreOrderProfitsharingRepository;
  14. use app\common\repositories\store\order\StoreOrderRepository;
  15. use app\common\repositories\store\ExcelRepository;
  16. use app\common\repositories\store\order\StoreRefundOrderRepository;
  17. use app\common\repositories\store\StoreActivityRelatedRepository;
  18. use app\common\repositories\system\financial\FinancialRepository;
  19. use app\common\repositories\system\form\FormRepository;
  20. use app\common\repositories\system\merchant\FinancialRecordRepository;
  21. use app\common\repositories\system\merchant\MerchantIntentionRepository;
  22. use app\common\repositories\user\UserBillRepository;
  23. use app\common\repositories\user\UserExtractRepository;
  24. use app\common\repositories\user\UserFieldsRepository;
  25. use app\common\repositories\user\UserInfoRepository;
  26. use app\common\repositories\user\UserLabelRepository;
  27. use app\common\repositories\user\UserRepository;
  28. use app\common\repositories\user\UserVisitRepository;
  29. use think\Exception;
  30. use think\exception\ValidateException;
  31. use think\facade\Cache;
  32. use think\facade\Db;
  33. class ExcelService
  34. {
  35. public $paytype = [0 => '余额', 1 => '微信', 2 => '微信', 3 => '微信', 4 => '支付宝', 5 => '支付宝', 6 => '微信',7 => '线下支付'];
  36. public function getAll($data)
  37. {
  38. set_time_limit(0);
  39. ini_set('memory_limit', '-1');
  40. $this->{$data['type']}($data['where'], $data['excel_id']);
  41. }
  42. /**
  43. * 导出操作
  44. * @param $id
  45. * @param $path
  46. * @param $header
  47. * @param $title
  48. * @param array $export
  49. * @param string $filename
  50. * @param array $end
  51. * @param string $suffix
  52. * @author Qinii
  53. * @day 3/17/21
  54. */
  55. public function export($id, $path, $header, $title, $export = [], $filename = '', $end = [], $suffix = 'xlsx')
  56. {
  57. try {
  58. $_path = SpreadsheetExcelService::instance()
  59. ->createOrActive($id)
  60. ->setExcelHeader($header, count($title['mark']) + 2)
  61. ->setExcelTile($title)
  62. ->setExcelContent($export)
  63. ->setExcelEnd($end)
  64. ->excelSave($filename, $suffix, $path);
  65. app()->make(ExcelRepository::class)->update($id, [
  66. 'name' => $filename . '.' . $suffix,
  67. 'status' => 1,
  68. 'path' => '/' . $_path
  69. ]);
  70. } catch (Exception $exception) {
  71. app()->make(ExcelRepository::class)->update($id, [
  72. 'name' => $filename . '.' . $suffix,
  73. 'status' => 2,
  74. 'message' => $exception->getMessage()
  75. ]);
  76. }
  77. }
  78. /**
  79. * 搜索记录导出
  80. * @param array $where
  81. * @param int $id
  82. * @author xaboy
  83. * @day 6/10/21
  84. */
  85. public function searchLog(array $where, int $page, int $limit)
  86. {
  87. $header = ['序号', '用户ID', '用户昵称', '用户类型', '搜索词', '搜索时间', '首次访问时间'];
  88. $user_type = [
  89. 'h5' => 'H5',
  90. 'wechat' => '公众号',
  91. 'routine' => '小程序',
  92. ];
  93. $export = [];
  94. $title = [];
  95. $query = app()->make(UserVisitRepository::class)->search($where)->with(['user' => function ($query) {
  96. $query->field('uid,nickname,avatar,user_type,create_time');
  97. }])->order('create_time DESC');
  98. $count = $query->count();
  99. $logs = $query->page($page, $limit)->select();
  100. foreach ($logs as $log) {
  101. $export[] = [
  102. $log['user_visit_id'],
  103. $log['user'] ? $log['user']['uid'] : '未登录',
  104. $log['user'] ? $log['user']['nickname'] : '未知',
  105. $log['user'] ? ($user_type[$log['user']['user_type']] ?? $log['user']['user_type']) : '未知',
  106. $log['content'],
  107. $log['create_time'],
  108. $log['user'] ? $log['user']['create_time'] : '未知',
  109. ];
  110. }
  111. $filename = '搜索记录_' . date('YmdHis');
  112. $foot = [];
  113. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  114. }
  115. /**
  116. * 导出订单
  117. * @param array $where
  118. * @param int $id
  119. * @author Qinii
  120. * @day 2020-08-10
  121. */
  122. public function order(array $where, int $page, int $limit)
  123. {
  124. //订单状态(0:待发货;1:待收货;2:待评价;3:已完成; 9: 拼团中 10: 待付尾款 11:尾款超时未付 -1:已退款)
  125. $statusType = [0 => '待发货', 1 => '待收货', 2 => '待评价', 3 => '已完成', 9 => '拼团中', 10 => '待付尾款', 11 => '尾款超时未付', -1
  126. => '已退款'];
  127. $make = app()->make(StoreOrderRepository::class);
  128. $status = $where['status'];
  129. $del = $where['mer_id'] > 0 ? 0 : null;
  130. unset($where['status']);
  131. $query = $make->search($where, $del)->where($make->getOrderType($status))->with([
  132. 'orderProduct',
  133. 'merchant' => function ($query) {
  134. return $query->field('mer_id,mer_name');
  135. },
  136. 'user',
  137. 'spread',
  138. ])->order('order_id ASC');
  139. $count = $query->count();
  140. $list = $query->page($page, $limit)->select()->append(['refund_price']);
  141. $export = [];
  142. foreach ($list as $item) {
  143. $product = [];
  144. foreach ($item['orderProduct'] as $value) {
  145. $product[] = [
  146. $value['cart_info']['product']['store_name'],
  147. $value['cart_info']['productAttr']['sku'] ?: '无',
  148. $value['product_num'] . ' ' . $value['unit_name'],
  149. $value['cart_info']['productAttr']['price'],
  150. $value['cart_info']['productAttr']['cost'],
  151. ];
  152. }
  153. $one = [
  154. $item['merchant']['mer_name'],
  155. $item['order_sn'],
  156. $item['paid'] ? ($statusType[$item['status']] ?? '无') : '未支付',
  157. $item['order_type'] ? '核销订单' : (($item['is_virtual'] = 4) ? '预约订单':'普通订单'),
  158. $item['spread']['nickname'] ?? '无',
  159. $item['user']['nickname'] ?? $item['uid'],
  160. $product,
  161. $item['coupon_price'],
  162. $item['pay_postage'],
  163. $item['pay_price'],
  164. $item['refund_price'],
  165. $item['real_name'],
  166. $item['user_phone'],
  167. $item['user_address'] ?: '',
  168. $item['delivery_id'] ?: '',
  169. $item['create_time'],
  170. $this->paytype[$item['pay_type']],
  171. $item['paid'] ? '已支付' : '未支付',
  172. $item['remark'] ?: '',
  173. $item['is_del'] ? '是' : '否',
  174. $item['order_extend'] ?? ''
  175. ];
  176. $export[] = $one;
  177. }
  178. $header = ['商户名称', '订单编号', '订单状态', '订单类型', '推广人', '用户信息', '商品名称', '商品规格', '商品数量', '商品价格', '商品成本价' ,'优惠', '实付邮费(元)', '实付金额(元)', '已退款金额(元)', '收货人', '收货人电话', '收货地址', '物流/电话', '下单时间', '支付方式', '支付状态', '商家备注', '是否删除','系统表单信息'];
  179. $filename = '订单列表_' . date('YmdHis');
  180. $title = ['订单列表', '导出时间:' . date('Y-m-d H:i:s', time())];
  181. $foot = '';
  182. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  183. }
  184. /**
  185. * 导出订单
  186. * @param array $where
  187. * @param int $id
  188. * @author Qinii
  189. * @day 2020-08-10
  190. */
  191. public function pointsOrder(array $where, int $page, int $limit)
  192. {
  193. //订单状态(0:待发货;1:待收货;2:待评价;3:已完成; 9: 拼团中 10: 待付尾款 11:尾款超时未付 -1:已退款)
  194. $statusType = [0 => '待发货', 1 => '待收货', 2 => '待评价', 3 => '已完成', 9 => '拼团中', 10 => '待付尾款', 11 => '尾款超时未付', -1 => '已退款',];
  195. $paytype = [0 => '余额', 1 => '微信', 2 => '小程序', 3 => 'H5', 4 => '支付宝', 5 => '支付宝扫码', 6 => '微信扫码',7 => '线下支付'];
  196. $make = app()->make(StoreOrderRepository::class);
  197. // $status = $where['status'];
  198. // unset($where['status']);
  199. if ($where['status'] == -10) {
  200. unset($where['status']);
  201. $where['is_del'] = 1;
  202. }
  203. $query = $make->searchAll($where, 0, 1)->with([
  204. 'orderProduct',
  205. 'user',
  206. ])->order('order_id ASC');
  207. $count = $query->count();
  208. $list = $query->page($page, $limit)->select();
  209. $export = [];
  210. foreach ($list as $item) {
  211. $product = [];
  212. foreach ($item['orderProduct'] as $value) {
  213. $product[] = [
  214. $value['cart_info']['product']['store_name'],
  215. $value['cart_info']['productAttr']['sku'] ?: '无',
  216. $value['product_num'] . ' ' . $value['unit_name'],
  217. $value['cart_info']['productAttr']['price']
  218. ];
  219. }
  220. $one = [
  221. $item['order_sn'],
  222. $item['is_del'] ? '用户已删除' : ($item['paid'] ? ($statusType[$item['status']] ?? '无') : '未支付'),
  223. $item['user']['nickname'] ?? $item['uid'],
  224. $product,
  225. $item['integral'],
  226. $item['pay_postage'],
  227. $value['product_price'],
  228. $item['real_name'],
  229. $item['user_phone'],
  230. $item['user_address'] ?: '',
  231. $item['delivery_id'] ?: '',
  232. $item['create_time'],
  233. $paytype[$item['pay_type']],
  234. $item['paid'] ? '已支付' : '未支付',
  235. $item['remark'] ?: '',
  236. $item['is_system_del'] ? '是' : '否',
  237. ];
  238. $export[] = $one;
  239. }
  240. $header = ['订单编号', '订单状态', '用户信息', '商品名称', '商品规格', '商品数量', '商品价格', '兑换积分', '实付邮费(元)', '实付金额(元)', '收货人', '收货人电话', '收货地址', '物流/电话', '下单时间', '支付方式', '支付状态', '商家备注', '后台是否删除'];
  241. $filename = '积分订单列表_' . date('YmdHis');
  242. $title = ['积分订单列表', '导出时间:' . date('Y-m-d H:i:s', time())];
  243. $foot = '';
  244. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  245. }
  246. /**
  247. * 流水记录导出
  248. * @param array $where
  249. * @param int $id
  250. * @author Qinii
  251. * @day 2020-08-10
  252. */
  253. public function financial(array $where, int $page, int $limit)
  254. {
  255. $_key = [
  256. 'mer_accoubts' => '财务对账',
  257. 'sys_accoubts' => '财务对账',
  258. 'refund_order' => '退款订单',
  259. 'brokerage_one' => '一级分佣',
  260. 'brokerage_two' => '二级分佣',
  261. 'refund_brokerage_one' => '返还一级分佣',
  262. 'refund_brokerage_two' => '返还二级分佣',
  263. 'order' => '订单支付',
  264. 'order_platform_coupon' => '平台优惠券补贴',
  265. 'refund_platform_coupon' => '退回平台优惠券',
  266. 'order_svip_coupon' => '付费会员卷',
  267. 'refund_svip_coupon' => '退回付费会员卷',
  268. 'points_order_true' => '积分订单入账',
  269. 'svip' => '支付会员费',
  270. ];
  271. $make = app()->make(FinancialRecordRepository::class);
  272. $query = $make->search($where)->with([
  273. 'merchant',
  274. 'orderInfo',
  275. 'refundOrder',
  276. 'userOrder'
  277. ]);
  278. $header = ['商户名称', '交易流水单号', '类型', '总订单号', '订单号/退款单号', '用户名', '用户ID', '交易类型','支付方式','第三方交易单号', '收入/支出', '金额',
  279. '创建时间'];
  280. $title = [
  281. '流水列表',
  282. '生成时间:' . date('Y-m-d H:i:s', time())
  283. ];
  284. $export = [];
  285. $count = $query->count();
  286. $list = $query->order('create_time DESC')->page($page, $limit)->select();
  287. foreach ($list as $v) {
  288. $wx = (substr($v['order_sn'], 0, 2) === 'wx');
  289. $export[] = [
  290. $v['merchant']['mer_name'] ?? ($v['mer_id'] ? '未知商户' : '平台'),
  291. $v['financial_record_sn'],
  292. $wx ? ($v['financial_type'] == 'svip' ? '付费会员单' : '订单') : '退款单',
  293. $wx ? ($v['financial_type'] == 'svip' ? '' : $v['orderInfo']['groupOrder']['group_order_sn']) : '',
  294. $v['order_sn'],
  295. $v['user_info'],
  296. $v['user_id'],
  297. $_key[$v['financial_type']],
  298. $v['financial_type'] == 'order' ? $this->paytype[$v['orderInfo']['pay_type']] : '',
  299. $wx ? ($v['orderInfo']['transaction_id'] ?: '') : "",
  300. $v['financial_pm'] ? '收入' : '支出',
  301. ($v['financial_pm'] ? '+ ' : '- ') . $v['number'],
  302. $v['create_time'],
  303. ];
  304. }
  305. $filename = '流水列表_' . date('YmdHis');
  306. $foot = [];
  307. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  308. }
  309. /**
  310. * 获取待发货订单 发货信息
  311. * @param array $where
  312. * @param int $id
  313. * @author Qinii
  314. * @day 3/13/21
  315. */
  316. public function delivery(array $where, int $page, int $limit)
  317. {
  318. $make = app()->make(StoreOrderRepository::class);
  319. $where['order_type'] = 0;
  320. $where['is_del'] = 0;
  321. $where['filter_product'] = 1;
  322. $query = $make->search($where)->with(['orderProduct'])->order('order_id ASC');
  323. $header = ['序号', '订单编号', '物流公司', '物流编码', '物流单号', '发货地址', '用户信息', '手机号', '商品信息', '支付时间','用户备注'];
  324. $title = [
  325. '批量发货单',
  326. '生成时间:' . date('Y-m-d H:i:s', time()). '物流编码在:[ 设置 => 物流公司 ] 菜单中查看',
  327. ];
  328. $filename = '批量发货单_' . date('YmdHis');
  329. $export = [];
  330. $count = $query->count();
  331. $data = $query->page($page, $limit)->select();
  332. foreach ($data as $k => $item) {
  333. $product = '';
  334. foreach ($item['orderProduct'] as $value) {
  335. $product = $product . $value['cart_info']['product']['store_name'] . '【' . $value['cart_info']['productAttr']['sku'] . '】【' . $value['refund_num'] . '】' . PHP_EOL;
  336. }
  337. $export[] = [
  338. $k + 1,
  339. $item['order_sn'] ?? '',
  340. '',
  341. $item['delivery_name'] ?? "",
  342. $item['delivery_id'] ?? "",
  343. $item['user_address'] ?? "",
  344. $item['real_name'] ?? '',
  345. $item['user_phone'] ?? '',
  346. $product,
  347. $item['pay_time'] ?? '',
  348. $item['mark'] ?? '',
  349. ];
  350. }
  351. $foot = [];
  352. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  353. }
  354. /**
  355. * 导出 发货导入记录
  356. * @param array $where
  357. * @param int $id
  358. * @author Qinii
  359. * @day 3/17/21
  360. */
  361. public function importDelivery(array $where, int $page, int $limit)
  362. {
  363. $make = app()->make(StoreImportDeliveryRepository::class);
  364. $query = $make->getSearch($where)->order('create_time ASC');
  365. $title = [
  366. '发货记录',
  367. '生成时间:' . date('Y-m-d H:i:s', time())
  368. ];
  369. $header = ['订单编号', '物流公司', '物流单号', '发货状态', '备注'];
  370. $filename = '发货单记录_' . date('YmdHis');
  371. $export = [];
  372. $count = $query->count();
  373. $data = $query->page($page, $limit)->select();
  374. foreach ($data as $item) {
  375. $export[] = [
  376. $item['order_sn'],
  377. $item['delivery_name'],
  378. $item['delivery_id'],
  379. $item['status'],
  380. $item['mark'],
  381. ];
  382. }
  383. $foot = [];
  384. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  385. }
  386. /**
  387. * 平台/商户 导出日月账单信息
  388. * @param array $where
  389. * @param int $id
  390. * @author Qinii
  391. * @day 3/25/21
  392. */
  393. public function exportFinancial(array $where, int $page, int $limit)
  394. {
  395. /*
  396. order 收入 公共 新订单
  397. brokerage_one 支出 公共 一级佣金
  398. brokerage_two 支出 公共 二级佣金
  399. order_charge 支出 商户 手续费
  400. order_true 支出 平台 商户入账
  401. refund_order 支出 公共 退款
  402. refund_brokerage_one 收入 公共 返还一级佣金
  403. refund_brokerage_two 收入 公共 返还二级佣金
  404. refund_charge 收入 商户 返还手续费
  405. refund_true 收入 平台 商户返还入账
  406. presell 收入 公共 新订单
  407. presell_charge 支出 商户 手续费
  408. presell_true 支出 平台 商户入账
  409. */
  410. $financialType = [
  411. 'order' => '订单支付',
  412. 'presell' => '预售订单(尾款)',
  413. 'brokerage_one' => '一级佣金',
  414. 'brokerage_two' => '二级佣金',
  415. 'order_charge' => '手续费',
  416. 'order_true' => '商户入账',
  417. 'refund_order' => '退款',
  418. 'refund_charge' => '返还手续费',
  419. 'refund_true' => '商户返还入账',
  420. 'presell_charge' => '预售订单(手续费)',
  421. 'presell_true' => '商户入账',
  422. 'refund_brokerage_one' => '返还一级佣金',
  423. 'refund_brokerage_two' => '返还二级佣金',
  424. 'mer_presell' => '预售订单(总额)',
  425. 'order_presell' => '预售订单(定金)',
  426. 'refund_platform_coupon' => '退回优惠券补贴',
  427. 'order_platform_coupon' => '优惠券补贴',
  428. 'order_svip_coupon' => '付费会员卷',
  429. 'refund_svip_coupon' => '退回付费会员卷',
  430. 'points_order_true' => '积分订单入账',
  431. 'svip' => '购买付费会员入账',
  432. ];
  433. $sys_pm_1 = ['order', 'presell', 'order_charge', 'order_presell', 'presell_charge', 'refund_brokerage_one', 'refund_brokerage_two', 'points_order_true','svip'];
  434. $mer_pm_1 = ['order', 'presell', 'refund_charge', 'refund_brokerage_one', 'refund_brokerage_two', 'mer_presell', 'order_platform_coupon'];
  435. $date_ = $where['date'];
  436. unset($where['date']);
  437. $make = app()->make(FinancialRecordRepository::class);
  438. $query = $make->search($where)->with(['orderInfo', 'refundOrder', 'merchant.merchantCategory']);
  439. if ($where['type'] == 1) {
  440. $title_ = '日账单';
  441. $start_date = $date_ . ' 00:00:00';
  442. $end_date = $date_ . ' 23:59:59';
  443. $query->whereDay('create_time', $date_);
  444. } else {
  445. $title_ = '月账单';
  446. $start_date = (date('Y-m-01', strtotime($date_)));
  447. $end_date = date('Y-m-d', strtotime("$start_date +1 month -1 day"));
  448. $query->whereMonth('create_time', $date_);
  449. }
  450. $income = $make->countIncome($where['type'], $where, $date_);
  451. $expend = $make->countExpend($where['type'], $where, $date_);
  452. $charge = bcsub($income['number'], $expend['number'], 2);
  453. $filename = $title_ . '(' . $date_ . ')' . time();
  454. $export = [];
  455. $count = $query->count();
  456. $i = 1;
  457. //平台
  458. if (!$where['is_mer']) {
  459. $header = ['商户类别', '商户分类', '商户名称', '总订单号', '订单编号','支付方式', '交易流水号', '交易时间','第三方交易单号', '对方信息', '交易类型',
  460. '收支金额', '备注'];
  461. $list = $query->page($page, $limit)->order('financial_record_id DESC')->select();
  462. foreach ($list as $value) {
  463. try {
  464. $export[] = [
  465. $value['merchant'] ? $value['merchant']['is_trader'] ? '自营' : '非自营' : '平台',
  466. $value['merchant']['merchantCategory']['category_name'] ?? '平台',
  467. $value['merchant']['mer_name'] ?? '平台',
  468. $value['orderInfo']['group_order_sn'] ?? '无数据',
  469. $value['order_sn'],
  470. $this->paytype[$value['orderInfo']['pay_type']] ?? '',
  471. $value['financial_record_sn'],
  472. $value['create_time'],
  473. ($value['orderInfo']['transaction_id']) ?? ($value['orderInfo']['transaction_id'] ?: ''),
  474. $value['user_info'],
  475. $financialType[$value['financial_type']],
  476. (in_array($value['financial_type'], $sys_pm_1) ? '+' : '-') . $value['number'],
  477. ''
  478. ];
  479. } catch (Exception $exception) {
  480. halt($exception->getLine(),$exception->getMessage(),$value);
  481. }
  482. }
  483. $foot = [
  484. '合计:平台应入账手续费 ' . $charge,
  485. '收入合计: ' . '订单支付' . $income['count'] . '笔,' . '实际支付金额共:' . $income['number'] . '元',
  486. '支出合计: ' . '佣金支出' . $expend['count_brokerage'] . '笔,支出金额:' . $expend['number_brokerage'] . '元;商户入账支出' . $expend['count_order'] . '笔,支出金额:' . $expend['number_order'] . '元;退款手续费' . $expend['count_charge'] . '笔,支出金额' . $expend['number_charge'] .'元;线下商户已收款' .$expend['count_offline']. '笔,金额:'.$expend['number_offline'] . '元;合计支出' . $expend['number'],
  487. ];
  488. //商户
  489. } else {
  490. $header = ['序号', '总订单号', '子订单编号', '交易流水号', '交易时间','支付方式', '对方信息', '交易类型','第三方交易单号', '收支金额', '备注'];
  491. $mer_name = '';
  492. $list = $query->page($page, $limit)->order('financial_record_id DESC')->select();
  493. foreach ($list as $value) {
  494. try{
  495. $export[] = [
  496. $i,
  497. $value['orderInfo']['groupOrder']['group_order_sn'] ?? '无数据',
  498. $value['orderInfo']['order_sn'] ?? '',
  499. $value['financial_record_sn'],
  500. $value['orderInfo']['create_time'],
  501. $this->paytype[$value['orderInfo']['pay_type']] ?? '',
  502. $value['user_info'],
  503. $financialType[$value['financial_type']],
  504. ($value['orderInfo']['transaction_id']) ?? ($value['orderInfo']['transaction_id'] ?: ''),
  505. (in_array($value['financial_type'], $mer_pm_1) ? '+' : '-') . $value['number'],
  506. ''
  507. ];
  508. $i++;
  509. $mer_name = $mer_name ? : ($value['merchant']['mer_name'] ?? '');
  510. }catch (\Exception $exception) {
  511. halt($exception->getLine(),$exception->getMessage(),$value);
  512. }
  513. }
  514. $count_brokeage = $expend['count_brokerage'] + $expend['count_refund_brokerage'];
  515. $number_brokeage = bcsub($expend['number_brokerage'], $expend['number_refund_brokerage'], 2);
  516. $count_charge = $expend['count_charge'] + $expend['count_order_charge'];
  517. $number_charge = bcsub($expend['number_order_charge'], $expend['number_charge'], 2);
  518. $foot = [
  519. '合计:商户应入金额 ' . $charge,
  520. '收入合计: ' . '订单支付' . $income['count'] . '笔,' . '实际支付金额共:' . $income['number'] . '元;线下收入' . $income['count_offline'] . '笔,金额:' . $income['number_offline'] . '元',
  521. '支出合计: ' . '佣金支出' . $count_brokeage . '笔,支出金额:' . $number_brokeage . '元;退款' . $expend['count_refund'] . '笔,支出金额:' . $expend['number_refund'] . '元;平台手续费' . $count_charge . '笔,支出金额:' . $number_charge . '元;合计支出金额:' . $expend['number'] . '元;',
  522. ];
  523. $mer_name = '商户名称:' . $mer_name;
  524. }
  525. $title = [
  526. $title_,
  527. $mer_name ?? '平台',
  528. '结算账期:【' . $start_date . '】至【' . $end_date . '】',
  529. '生成时间:' . date('Y-m-d H:i:s', time())
  530. ];
  531. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  532. }
  533. /**
  534. * 退款单导出
  535. * @param array $where
  536. * @param int $id
  537. * @author Qinii
  538. * @day 6/10/21
  539. */
  540. public function refundOrder(array $where, int $page, int $limit)
  541. {
  542. $query = app()->make(StoreRefundOrderRepository::class)->search($where)
  543. ->where('is_system_del', 0)->with([
  544. 'order' => function ($query) {
  545. $query->field('order_id,order_sn,activity_type,real_name,user_address');
  546. },
  547. 'refundProduct.product',
  548. 'user' => function ($query) {
  549. $query->field('uid,nickname,phone');
  550. },
  551. 'merchant' => function ($query) {
  552. $query->field('mer_id,mer_name');
  553. },
  554. ])->order('StoreRefundOrder.create_time DESC');
  555. $title = [
  556. '退款订单',
  557. '生成时间:' . date('Y-m-d H:i:s', time())
  558. ];
  559. $header = ['商户名称', '退款单号', '申请时间', '最新更新时间', '退款金额', '退货件量', '退货商品信息', '退款类型', '订单状态', '拒绝理由', '退货人', '退货地址', '相关订单号', '退货物流公司', '退货物流单号', '备注'];
  560. $filename = '退款订单' . time();
  561. $status = [
  562. 0 => '待审核',
  563. 1 => '待退货',
  564. 2 => '待收货',
  565. 3 => '已退款',
  566. 4 => '平台介入',
  567. -1 => '审核未通过',
  568. -2 => '退款失败',
  569. -10 => '用户取消',
  570. ];
  571. $count = $query->count();
  572. $data = $query->page($page, $limit)->select()->toArray();
  573. $export = [];
  574. foreach ($data as $datum) {
  575. $product = '';
  576. foreach ($datum['refundProduct'] as $value) {
  577. $product .= '【' . $value['product']['cart_info']['product']['product_id'] . '】' . $value['product']['cart_info']['product']['store_name'] . '*' . $value['refund_num'] . $value['product']['cart_info']['product']['unit_name'] . PHP_EOL;
  578. }
  579. $export[] = [
  580. $datum['merchant']['mer_name'] ?? '',
  581. $datum['refund_order_sn'],
  582. $datum['create_time'],
  583. $datum['status_time'] ?? ' ',
  584. $datum['refund_price'],
  585. $datum['refund_num'],
  586. $product,
  587. ($datum['refund_type'] == 1) ? '仅退款' : '退款退货',
  588. $status[$datum['status']] ?? '',
  589. $datum['fail_message']?? '',
  590. $datum['order']['real_name'] ?? '',
  591. $datum['order']['user_address']?? '',
  592. $datum['order']['order_sn']?? '',
  593. $datum['delivery_type']?? '',
  594. $datum['delivery_id'] ?? '',
  595. $datum['mark'],
  596. ];
  597. }
  598. $foot = '';
  599. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  600. }
  601. /**
  602. * 积分日志导出
  603. * @param $where
  604. * @param $id
  605. * @author Qinii
  606. * @day 6/10/21
  607. */
  608. public function integralLog($where, int $page, int $limit)
  609. {
  610. $title = [
  611. '积分日志',
  612. '生成时间:' . date('Y-m-d H:i:s', time())
  613. ];
  614. $header = ['用户ID', '用户昵称', '积分标题', '变动积分', '当前积分余额', '备注', '时间'];
  615. $filename = '积分日志' . time();
  616. $export = [];
  617. $query = app()->make(UserBillRepository::class)->searchJoin($where)->order('a.create_time DESC');
  618. $count = $query->count();
  619. $list = $query->page($page, $limit)->select();
  620. foreach ($list as $item) {
  621. $export[] = [
  622. $item['uid'],
  623. $item['nickname'],
  624. $item['title'],
  625. $item['number'],
  626. $item['balance'],
  627. $item['mark'],
  628. $item['create_time'],
  629. ];
  630. }
  631. $foot = '';
  632. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  633. }
  634. public function intention($where, int $page, int $limit)
  635. {
  636. $title = [
  637. '申请列表',
  638. '生成时间:' . date('Y-m-d H:i:s', time())
  639. ];
  640. $header = ['商户姓名', '联系方式', '备注', '店铺名称', '店铺分类', '时间'];
  641. $filename = '申请列表' . time();
  642. $export = [];
  643. $query = app()->make(MerchantIntentionRepository::class)->search($where)->with(['merchantCategory', 'merchantType'])->order('a.create_time DESC');
  644. $count = $query->count();
  645. $list = $query->page($page, $limit)->select();
  646. foreach ($list as $item) {
  647. $export[] = [
  648. $item['name'],
  649. $item['phone'],
  650. $item['mark'],
  651. $item['mer_name'],
  652. $item['category_name'],
  653. $item['create_time'],
  654. ];
  655. }
  656. $foot = '';
  657. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  658. }
  659. /**
  660. * 转账记录
  661. * @param array $where
  662. * @param int $id
  663. * @author Qinii
  664. * @day 9/28/21
  665. */
  666. public function financialLog(array $where, int $page, int $limit)
  667. {
  668. $title = [
  669. '转账记录',
  670. '生成时间:' . date('Y-m-d H:i:s', time())
  671. ];
  672. $header = ['商户名称', '申请时间', '转账金额', '到账状态', '审核状态', '拒绝理由', '商户余额', '转账信息'];
  673. $filename = '转账记录_' . time();
  674. $export = [];
  675. $query = app()->make(FinancialRepository::class)->search($where)->with('merchant');
  676. $count = $query->count();
  677. $list = $query->page($page, $limit)->select();
  678. foreach ($list as $item) {
  679. switch ($item->financial_type) {
  680. case 1:
  681. $acount = '姓名:' . $item->financial_account->name . PHP_EOL;
  682. $acount .= '银行名称:' . $item->financial_account->bank . PHP_EOL;
  683. $acount .= '银行卡号:' . $item->financial_account->bank_code;
  684. break;
  685. case 2:
  686. $acount = '姓名:' . $item->financial_account->name . PHP_EOL;
  687. $acount .= '微信号:' . $item->financial_account->wechat . PHP_EOL;
  688. $acount .= '收款二维码地址:' . $item->financial_account->wechat_code;
  689. break;
  690. case 3:
  691. $acount = '姓名:' . $item->financial_account->name . PHP_EOL;
  692. $acount .= '支付宝号:' . $item->financial_account->alipay . PHP_EOL;
  693. $acount .= '收款二维码地址:' . $item->financial_account->alipay_code;
  694. break;
  695. }
  696. $export[] = [
  697. $item->merchant->mer_name,
  698. $item->create_time,
  699. $item->extract_money,
  700. $item->financial_status == 1 ? '已转账' : '未转账',
  701. $item->status == 1 ? '通过' : ($item->status == 0 ? '待审核' : '拒绝'),
  702. $item->refusal,
  703. $item->mer_money,
  704. $acount,
  705. ];
  706. }
  707. $foot = '';
  708. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  709. }
  710. /**
  711. * 用户提现申请
  712. * @param array $where
  713. * @param int $id
  714. * @author Qinii
  715. * @day 9/28/21
  716. */
  717. public function extract(array $where, int $page, int $limit)
  718. {
  719. $title = [
  720. '提现申请',
  721. '生成时间:' . date('Y-m-d H:i:s', time())
  722. ];
  723. $type = [
  724. '银行卡',
  725. '微信',
  726. '支付宝',
  727. '微信零钱',
  728. '提现到余额'
  729. ];
  730. $header = ['用户名', '用户UID', '提现金额', '余额', '审核状态', '拒绝理由', '提现方式', '转账信息'];
  731. $filename = '提现申请_' . time();
  732. $path = 'extract';
  733. $export = [];
  734. $query = app()->make(UserExtractRepository::class)->search($where)->with(['user' => function ($query) {
  735. // 关联查询用户信息,只获取 uid, avatar, nickname 三个字段
  736. $query->field('uid,avatar,nickname');
  737. }]);;
  738. $count = $query->count();
  739. $list = $query->page($page, $limit)->select();
  740. foreach ($list as $item) {
  741. $acount = '';
  742. if ($item->extract_type == 0) {
  743. $acount .= '银行地址:' . $item->bank_address . PHP_EOL;
  744. $acount .= '银行卡号:' . $item->bank_code;
  745. }
  746. if ($item->extract_type == 2) {
  747. $acount .= '微信号:' . $item->wechat . PHP_EOL;
  748. $acount .= '收款二维码地址:' . $item->extract_pic;
  749. }
  750. if ($item->extract_type == 1) {
  751. $acount .= '支付宝号:' . $item->alipay . PHP_EOL;
  752. $acount .= '收款二维码地址:' . $item->extract_pic;
  753. }
  754. $export[] = [
  755. $item->user->nickname,
  756. $item->uid,
  757. $item->extract_price,
  758. $item->balance,
  759. $item->status == 1 ? '通过' : ($item->status == 0 ? '待审核' : '拒绝'),
  760. $item->fail_msg,
  761. $type[$item->extract_type],
  762. $acount,
  763. ];
  764. }
  765. $foot = '';
  766. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  767. }
  768. /**
  769. * 分账管理
  770. * @param array $where
  771. * @param int $id
  772. * @author Qinii
  773. * @day 9/28/21
  774. */
  775. public function profitsharing(array $where, int $page, int $limit)
  776. {
  777. $title = [
  778. '分账明细',
  779. '生成时间:' . date('Y-m-d H:i:s', time())
  780. ];
  781. $header = ['订单编号', '商户名称', '订单类型', '状态', '分账时间', '订单金额'];
  782. $filename = '分账明细_' . time();
  783. $export = [];
  784. $query = app()->make(StoreOrderProfitsharingRepository::class)->search($where)->with('order', 'merchant')->order('create_time DESC');
  785. $count = $query->count();
  786. $list = $query->page($page, $limit)->select();
  787. foreach ($list as $item) {
  788. $info = '分账金额:' . $item->profitsharing_price . PHP_EOL;
  789. if (isset($item->profitsharing_price) && $item->profitsharing_price > 0) $info .= '退款金额:' . $item->profitsharing_refund . PHP_EOL;
  790. $info .= '分账给商户金额:' . $item->profitsharing_mer_price;
  791. $export[] = [
  792. $item->order->order_sn ?? '',
  793. $item->merchant->mer_name,
  794. $item->typeName,
  795. $item->statusName,
  796. $item->profitsharing_time,
  797. $info
  798. ];
  799. }
  800. $foot = '';
  801. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  802. }
  803. /**
  804. * 资金记录
  805. * @param array $where
  806. * @param int $id
  807. * @author Qinii
  808. * @day 9/28/21
  809. */
  810. public function bill(array $where, int $page, int $limit)
  811. {
  812. $title = [
  813. '资金记录',
  814. '生成时间:' . date('Y-m-d H:i:s', time())
  815. ];
  816. $header = ['用户ID', '昵称', '金额', '明细类型', '备注', '时间'];
  817. $filename = '资金记录_' . time();
  818. $export = [];
  819. $query = app()->make(UserBillRepository::class)
  820. ->searchJoin($where)->order('a.create_time DESC');
  821. $count = $query->count();
  822. $list = $query->page($page, $limit)->select();
  823. foreach ($list as $item) {
  824. $export[] = [
  825. $item->uid,
  826. $item->user->nickname ?? '',
  827. $item->number,
  828. $item->title,
  829. $item->mark,
  830. $item->create_time,
  831. ];
  832. }
  833. $export = array_reverse($export);
  834. $foot = '';
  835. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  836. }
  837. /**
  838. * 导出用户数据
  839. * @param array $where
  840. * @param int $page
  841. * @param int $limit
  842. * @return array
  843. * @throws \think\db\exception\DataNotFoundException
  844. * @throws \think\db\exception\DbException
  845. * @throws \think\db\exception\ModelNotFoundException
  846. *
  847. * @date 2023/09/27
  848. * @author yyw
  849. */
  850. public function user(array $where, int $page, int $limit, $viewSearch = [])
  851. {
  852. $userRepository = app()->make(UserRepository::class);
  853. $query = $userRepository->search($where, $viewSearch)->with([
  854. 'spread' => function ($query) {
  855. $query->with([
  856. 'spread' => function ($query) {
  857. $query->field('uid,nickname,spread_uid');
  858. }
  859. ])->field('uid,nickname,spread_uid');
  860. },
  861. 'member' => function ($query) {
  862. $query->field('user_brokerage_id,brokerage_level,brokerage_name,brokerage_icon');
  863. },
  864. 'group', 'getUserFields']);
  865. $count = $query->count();
  866. $list = $query->page($page, $limit)->select()->toArray();
  867. $header = ['用户ID', '昵称', '手机号码', '真实姓名', '性别', '用户账号', '用户生日', '推广员', '用户状态','付费会员','积分','余额','用户地址', '用户等级','成长值', '用户标签', '用户分组', '推广人', '上级推广人', '注册时间', '登录时间', '备注'];
  868. $filename = '用户列表_' . date('YmdHis');
  869. $title = ['用户列表', '导出时间:' . date('Y-m-d H:i:s', time())];
  870. $foot = '';
  871. $export = [];
  872. $userLabelRepository = app()->make(UserLabelRepository::class);
  873. /** @var UserInfoRepository $userInfoRepository */
  874. $userInfoRepository = app()->make(UserInfoRepository::class);
  875. $extend_info_fields = [];
  876. $extend_infos = $userInfoRepository->query(['is_used' => 1, 'is_default' => 0])->order('sort ASC')->select()->toArray();
  877. foreach ($extend_infos as $extend_info) {
  878. $header[] = $extend_info['title'];
  879. $extend_info_fields[$extend_info['field']] = $extend_info;
  880. }
  881. foreach ($list as $user) {
  882. $one = [
  883. $user['uid'],
  884. $user['nickname'],
  885. $user['phone'] ?: '无',
  886. $user['real_name'] ?: '无',
  887. ['保密', '男', '女'][$user['sex']] ?? '未知',
  888. $user['account'] ?: '无',
  889. $user['birthday'] ?: '无',
  890. ['否', '是'][$user['is_promoter']] ?? '未知',
  891. ['禁止', '正常'][$user['status']] ?? '未知',
  892. ['否', '是'][$user['is_svip'] > 0 ? 1 : 0] ?? '未知',
  893. $user['integral'],
  894. $user['now_money'],
  895. $user['addres'] ?: '无',
  896. $user['member']['brokerage_name'] ?? '无',
  897. $user['member_value'],
  898. count($user['label_id']) ? implode(',', $userLabelRepository->labels($user['label_id'])) : '无',
  899. $user['group']['group_name'] ?? '无',
  900. $user['spread']['nickname'] ?? '无',
  901. $user['spread']['spread']['nickname'] ?? '无',
  902. $user['create_time'],
  903. $user['last_time'],
  904. $user['mark'] ?: '无',
  905. ];
  906. foreach ($extend_info_fields as $field => $extend_info) {
  907. if (!empty($user['getUserFields'][$field])) {
  908. if ($extend_info['type'] == 'radio') {
  909. $one[] = $extend_info['content'][$user['getUserFields'][$field]];
  910. } else {
  911. $one[] = $user['getUserFields'][$field];
  912. }
  913. } else {
  914. $one[] = '无';
  915. }
  916. }
  917. $export[] = $one;
  918. }
  919. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  920. }
  921. /**
  922. * 导出用户提交的表单信息
  923. * @param $header
  924. * @param $info
  925. * @param $where
  926. * @param $page
  927. * @param $limit
  928. * @return array
  929. * @author Qinii
  930. * @day 2023/10/9
  931. */
  932. public function userForm($header, $info, $where, $page, $limit)
  933. {
  934. $storeActivityRelatedRepository = app()->make(StoreActivityRelatedRepository::class);
  935. $filename = '活动信息列表_' . date('YmdHis');
  936. $title = ['活动信息列表', '导出时间:' . date('Y-m-d H:i:s', time())];
  937. $foot = '';
  938. $export = [];
  939. $data = $storeActivityRelatedRepository->getList($where, $page, $limit);
  940. $count = $data['count'];
  941. //'活动名称','用户ID', '昵称', '手机号码'
  942. foreach ($data['list']->toArray() as $datum) {
  943. $_export = [
  944. $datum['activity']['activity_id'] ?? '',
  945. $datum['activity']['activity_name'] ?? '',
  946. $datum['uid'] ?? '0',
  947. $datum['nickname'] ?? '无',
  948. $datum['phone'] ?? '无',
  949. ];
  950. foreach ($info as $key) {
  951. $line_data = $datum['value'][$key] ?? '';
  952. if (is_array($line_data)) {
  953. $line_data = implode(',', $line_data);
  954. }
  955. array_push($_export, $line_data);
  956. }
  957. $_export[] = $datum['create_time'];
  958. $export[] = $_export;
  959. }
  960. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  961. }
  962. public function userFormLst($where, $page, $limit)
  963. {
  964. $storeActivityRelatedRepository = app()->make(storeActivityRelatedRepository::class);
  965. $query = $storeActivityRelatedRepository->search($where)->with([
  966. 'user' => function ($query) {
  967. $query->field('uid,nickname,avatar,phone');
  968. }
  969. ]);
  970. $count = $query->count();
  971. $list = $query->order('id DESC')->page($page, $limit)->select();
  972. $cache_key = json_encode($where);
  973. $keys = $list[0]['keys'] ?? [];
  974. if (!$header = Cache::get($cache_key)) {
  975. $header = ['用户昵称/ID', '手机号'];
  976. if ($keys) {
  977. foreach ($keys as $key) {
  978. $header[] = $key['label'];
  979. }
  980. }
  981. $header[] = '创建时间';
  982. Cache::set($cache_key, $header, 1800);
  983. }
  984. $export = [];
  985. foreach ($list as $item) {
  986. $_export = [
  987. $item['nickname'] . '/' . $item['uid'],
  988. $item['phone'],
  989. ];
  990. foreach ($keys as $key) {
  991. $line_data = $item['value'][$key['key']] ?? '';
  992. if (is_array($line_data)) {
  993. $line_data = implode('-', $line_data);
  994. }
  995. array_push($_export, $line_data);
  996. }
  997. array_push($_export, $item['create_time']);
  998. $export[] = $_export;
  999. }
  1000. $filename = '活动记录列表_' . date('YmdHis');
  1001. $title = ['活动记录列表', '导出时间:' . date('Y-m-d H:i:s', time())];
  1002. $foot = '';
  1003. return compact('count', 'header', 'title', 'export', 'foot', 'filename');
  1004. }
  1005. }