diff --git a/app/Admin/Actions/Exporter/GoodsSales.php b/app/Admin/Actions/Exporter/GoodsSales.php new file mode 100644 index 0000000..2f8135f --- /dev/null +++ b/app/Admin/Actions/Exporter/GoodsSales.php @@ -0,0 +1,86 @@ +params = $params; + } + + public function array(): array + { + $result = [[ + '下单时间', + '主订单号', + '商品ID', + '商品名称', + '市场', + '店铺', + '售价(元)', + '原价(元)', + '数量', + '单位', + '规格', + + ]]; + $data = $this->getData($this->params); + $markets = MarketModel::getMarketArray(); + $stores = StoreModel::getStoreArray(); + foreach ($data as $value){ + $specStr = ''; + if(!empty($value['spec'])){ + $specArr = json_decode($value['spec'],true); + if(isset($specArr[0]['spec_key'])){ + foreach($specArr as $spec){ + $specStr .= ' ['.$spec['spec_key'].':'.$spec['spec_value'].'] '; + } + } + } + $global_order_id = $value['global_order_id']??''; + $item = [ + date('Y-m_d H:i:s',$value['created_at']), + ' '.$global_order_id, + $value['goods_id'], + $value['name']??'', + $markets[$value['market_id']]??'', + $stores[$value['store_id']]??'', + $value['price']??0, + $value['original_price']??0, + $value['number']??0, + $value['goods_unit']??'', + $specStr??'' + ]; + + $result[] = $item; + } + return $result; + } + + /** + * 获取数据 + */ + public function getData($option = []) + { + $params = $option; + $repository = new GoodsReport(); + $selects = OrderGoodsModel::$tableName.'.goods_id,'.OrderGoodsModel::$tableName.'.name,price,original_price,goods_unit,spec,'.OrderMainModel::$tableName.'.market_id,'.OrderModel::$tableName.'.store_id,number,'.OrderMainModel::$tableName.'.created_at,global_order_id'; + $orderGoods = $repository->getDataModel($selects,$params); + $list = $orderGoods->get()->toArray(); + + return $list; + } + +} diff --git a/app/Admin/Actions/Tools/GoodsReportExport.php b/app/Admin/Actions/Tools/GoodsReportExport.php new file mode 100644 index 0000000..c569a13 --- /dev/null +++ b/app/Admin/Actions/Tools/GoodsReportExport.php @@ -0,0 +1,83 @@ +导出'; + + /** + * Handle the action request. + * + * @param Request $request + * + * @return Response + */ + public function handle(Request $request) + { + $url = '/goods_report_export?'; + $name = $request->get('name', ''); + $marketId = $request->get('market_id',0); + $storeId = $request->get('store_id',0); + $startTime = $request->get('start_time',''); + $endTime = $request->get('end_time',''); + + if(!empty($name)){ + $url .= '&name='.$name; + } + if(!empty($marketId)){ + $url .= '&market_id='.$marketId; + } + if(!empty($storeId)){ + $url .= '&store_id='.$storeId; + } + if(!empty($startTime)){ + $url .= '&start_time='.$startTime; + } + + if(!empty($endTime)){ + $url .= '&end_time='.$endTime; + } + return $this->response() + ->success('导出中~') + ->redirect($url); + } + public function parameters() + { + return [ + 'name' => request()->input('name', ''), + 'market_id' => request()->input('market_id',0), + 'store_id' => request()->input('store_id',0), + 'start_time' => request()->input('start_time',''), + 'end_time' => request()->input('end_time',''), + ]; + } + /** + * @return string|array|void + */ + public function confirm() + { + return '确定导出数据吗?'; + } + + /** + * @param Model|Authenticatable|HasPermissions|null $user + * + * @return bool + */ + protected function authorize($user): bool + { + return true; + } +} diff --git a/app/Admin/Controllers/v3/GoodsReportController.php b/app/Admin/Controllers/v3/GoodsReportController.php new file mode 100644 index 0000000..7802436 --- /dev/null +++ b/app/Admin/Controllers/v3/GoodsReportController.php @@ -0,0 +1,135 @@ +marketId = Auth::getMarket(); + + if($this->marketId){ + $this->newParams = ['market_id'=>$this->marketId]; + $builder = new GoodsReport($this->newParams); + $this->marketList = MarketModel::getMarketArray([['id','=',$this->marketId]]); + $this->storeList = StoreModel::getStoreArray([['market_id','=',$this->marketId]]); + }else{ + $builder = new GoodsReport(); + $this->marketList = MarketModel::getMarketArray(); + $this->storeList = StoreModel::getStoreArray(); + } + return Grid::make($builder, function (Grid $grid) { + $marketList = $this->marketList; + $storeList = $this->storeList; + $grid->column('goods_id')->sortable(); + $grid->column('cover_img')->image('',50); + $grid->column('name','商品名称'); + + $grid->column('market_id')->display(function($marketId){ + $item = MarketModel::getMarketInfo($marketId,'name'); + return $item->name ?? ''; + }); + $grid->column('store_id')->display(function($storeId){ + $item = StoreModel::getStoreInfo($storeId,'name'); + return $item->name ?? ''; + })->width('12%'); + $grid->column('price'); + $grid->column('original_price'); + $grid->column('number'); + $grid->column('created_at')->display(function($createdAt){ + return date('Y-m-d H:I:s',$createdAt) ?? ''; + }); + $grid->column('global_order_id')->help('统计订单状态为已完成的商品'); + + $grid->filter(function (Filter $filter) use($marketList,$storeList) { + // 更改为 panel 布局 + $filter->panel(); + $filter->equal('start_time','开始时间')->date()->width(2); + $filter->equal('end_time','结束时间')->date()->width(2); + $filter->equal('name','商品名称')->width(2); + if(!$this->marketId){ + $filter->equal('market_id','市场')->select($marketList)->width(2); + } + $filter->equal('store_id','店铺')->select($storeList)->width(2); + }); + + $grid->tools([ + new DataReportOption('today','goods_report','今日'), + new DataReportOption('yesterday','goods_report','昨日'), + new DataReportOption('this_week','goods_report','本周'), + new DataReportOption('last_week','goods_report','上周'), + new DataReportOption('this_month','goods_report','本月'), + new DataReportOption('last_month','goods_report','上月'), + new GoodsReportExport() + ]); + + // 每页1条 + $grid->paginate(10); + $grid->disableCreateButton(); + $grid->disableBatchActions(); + $grid->disableBatchDelete(); + + $grid->toolsWithOutline(); + + $grid->disableDeleteButton(); + $grid->disableEditButton(); + $grid->disableQuickEditButton(); + $grid->disableViewButton(); + $grid->disableActions(); + + $grid->disableRowSelector(); + }); + } + + /** + * 数据导出 + * @return \Symfony\Component\HttpFoundation\BinaryFileResponse + */ + public function export(Request $request) + { + $this->marketId = Auth::getMarket(); + $params = [ + 'name' => request()->input('name', ''), + 'market_id' => $this->marketId ? $this->marketId : request()->input('market_id',0), + 'store_id' => request()->input('store_id',0), + 'start_time' => request()->input('start_time',''), + 'end_time' => request()->input('end_time',''), + ]; + + $name = date('Y-m-d-His',time()); + $data = new \App\Admin\Actions\Exporter\GoodsSales($params); + if(empty($data)){ + return $this->error('没有数据!'); + } + return Excel::download($data, $name.'.xlsx'); + } +} diff --git a/app/Admin/Repositories/v3/GoodsActivityReport.php b/app/Admin/Repositories/v3/GoodsActivityReport.php index 47d1e6f..1452f26 100644 --- a/app/Admin/Repositories/v3/GoodsActivityReport.php +++ b/app/Admin/Repositories/v3/GoodsActivityReport.php @@ -6,6 +6,8 @@ use App\Models\LanzuOrderGoods as Model; use Dcat\Admin\Grid\Model as GridModel; use Dcat\Admin\Repositories\EloquentRepository; use Illuminate\Support\Facades\DB; +use App\Models\ImsCjdcOrderMain as OrderMainModel; +use App\Models\ImsCjdcOrder as OrderModel; class GoodsActivityReport extends EloquentRepository { @@ -37,9 +39,9 @@ class GoodsActivityReport extends EloquentRepository $where = ['market_id'=>$this->params['market_id']]; } - $selects = 'SUM(number) as total,SUM((original_price-price)*number) as subsidy_total,price,original_price,lanzu_order_goods.goods_id,lanzu_order_goods.name,lanzu_order_goods.cover_img,lanzu_order_main.market_id,lanzu_order.store_id'; + $selects = 'SUM(number) as total,SUM((original_price-price)*number) as subsidy_total,price,original_price,'.Model::$tableName.'.goods_id,'.Model::$tableName.'.name,'.Model::$tableName.'.cover_img,'.OrderMainModel::$tableName.'.market_id,'.OrderModel::$tableName.'.store_id'; $orderGoodsActivity = $this->getDataModel($selects,$where); - $list = $orderGoodsActivity->orderBy('total','desc')->groupBy('goods_id','lanzu_order_goods.name','cover_img','market_id','store_id','price','original_price')->paginate($perPage); + $list = $orderGoodsActivity->orderBy('total','desc')->groupBy('goods_id',Model::$tableName.'.name','cover_img','market_id','store_id','price','original_price')->paginate($perPage); $list = $list->toArray(); return $model->makePaginator( @@ -60,14 +62,14 @@ class GoodsActivityReport extends EloquentRepository $endTime = $params['end_time'] ?? request()->input('end_time',''); $orderGoodsActivity = Model::select(DB::raw($selects)) - ->join('lanzu_order','lanzu_order_goods.order_id','=','lanzu_order.id') - ->join('lanzu_order_main','lanzu_order.order_main_id','=','lanzu_order_main.global_order_id') - ->where('lanzu_order_goods.activity_type',2) - ->where('lanzu_order_goods.status',1) - ->whereIn('lanzu_order_main.state',[4,5,10,11]); + ->join(OrderModel::$tableName,Model::$tableName.'.order_id','=',OrderModel::$tableName.'.id') + ->join(OrderMainModel::$tableName,OrderModel::$tableName.'.order_main_id','=',OrderMainModel::$tableName.'.global_order_id') + ->where(Model::$tableName.'.activity_type',2) + ->where(Model::$tableName.'.status',1) + ->whereIn(OrderMainModel::$tableName.'.state',[4,5,10,11]); if($name){ - $orderGoodsActivity->where('lanzu_order_goods.name','like',"%$name%"); + $orderGoodsActivity->where(Model::$tableName.'.name','like',"%$name%"); } if($marketId){ $orderGoodsActivity->where('market_id',$marketId); @@ -76,28 +78,15 @@ class GoodsActivityReport extends EloquentRepository $orderGoodsActivity->where('store_id',$storeId); } if($startTime){ - $date = $startTime; $startTime = $startTime.' 00:00:00'; - $orderGoodsActivity->where('lanzu_order_goods.created_at','>=',strtotime($startTime)); - }else{ - $date = '2020-06-01'; + $orderGoodsActivity->where(Model::$tableName.'.created_at','>=',strtotime($startTime)); } if($endTime){ - $date = $date.' 至 '.$endTime; $endTime = $endTime.' 23:59:59'; - $orderGoodsActivity->where('lanzu_order_goods.created_at','<=',strtotime($endTime)); - }else{ - $date .= ' 至 '.$time; + $orderGoodsActivity->where(Model::$tableName.'.created_at','<=',strtotime($endTime)); } - // if(empty($startTime) && empty($endTime)){ - // $date = $time; - // $todayStart = $time.' 00:00:00'; - // $todayEnd = $time.' 23:59:59'; - // $orderGoodsActivity->where([['lanzu_order_goods.created_at','>=',strtotime($todayStart)]]); - // $orderGoodsActivity->where([['lanzu_order_goods.created_at','<=',strtotime($todayEnd)]]); - // } return $orderGoodsActivity; } @@ -107,9 +96,9 @@ class GoodsActivityReport extends EloquentRepository */ public function getCountData($params = []) { - $selects = "SUM(lanzu_order_goods.number) as total,SUM((original_price-price)*number) as subsidy_total,FROM_UNIXTIME(lanzu_order_goods.created_at,'%Y-%m-%d') as dtime"; + $selects = "SUM(".Model::$tableName.".number) as total,SUM((original_price-price)*number) as subsidy_total,FROM_UNIXTIME(".Model::$tableName.".created_at,'%Y-%m-%d') as dtime"; $orderGoodsActivity = $this->getDataModel($selects,$params); - $total = $orderGoodsActivity->orderBy('dtime','asc')->groupBy('dtime')->get()->toArray(); + $total = $orderGoodsActivity->orderBy('dtime','desc')->groupBy('dtime')->get()->toArray(); return $total ?? []; } @@ -119,7 +108,7 @@ class GoodsActivityReport extends EloquentRepository */ public function getMarketData($params = []) { - $selects = "SUM(lanzu_order_goods.number) as total,SUM((original_price-price)*number) as subsidy_total,market_id"; + $selects = "SUM(".Model::$tableName.".number) as total,SUM((original_price-price)*number) as subsidy_total,market_id"; $orderGoodsActivity = $this->getDataModel($selects,$params); $total = $orderGoodsActivity->groupBy('market_id')->get()->toArray(); diff --git a/app/Admin/Repositories/v3/GoodsReport.php b/app/Admin/Repositories/v3/GoodsReport.php new file mode 100644 index 0000000..2dc7b19 --- /dev/null +++ b/app/Admin/Repositories/v3/GoodsReport.php @@ -0,0 +1,116 @@ +params = $params; + } + + /** + * 获取统计列表数据 + */ + public function get(GridModel $model) + { + // 获取当前页数 + $currentPage = $model->getCurrentPage(); + // 获取每页显示行数 + $perPage = $model->getPerPage(); + + $where = []; + if(!empty($this->params) && isset($this->params['market_id']) && !empty($this->params['market_id'])){ + $where = ['market_id'=>$this->params['market_id']]; + } + + $selects = Model::$tableName.'.goods_id,'.Model::$tableName.'.name,price,original_price,'.Model::$tableName.'.cover_img,'.OrderMainModel::$tableName.'.market_id,'.OrderModel::$tableName.'.store_id,number,'.OrderMainModel::$tableName.'.created_at,global_order_id'; + $orderGoodsActivity = $this->getDataModel($selects,$where); + $list = $orderGoodsActivity->paginate($perPage); + $list = $list->toArray(); + + return $model->makePaginator( + $list['total'] ?? 0,$list['data'] ?? [] + ); + + } + + public function getDataModel($selects,$params = []) + { + // 获取筛选参数 + $name = $params['name'] ?? request()->input('name', ''); + $marketId = $params['market_id'] ?? request()->input('market_id',0); + $storeId = $params['store_id'] ?? request()->input('store_id',0); + + $startTime = $params['start_time'] ?? request()->input('start_time',''); + $endTime = $params['end_time'] ?? request()->input('end_time',''); + + $orderGoodsActivity = Model::select(DB::raw($selects)) + ->join(OrderModel::$tableName,Model::$tableName.'.order_id','=',OrderModel::$tableName.'.id') + ->join(OrderMainModel::$tableName,OrderModel::$tableName.'.order_main_id','=',OrderMainModel::$tableName.'.global_order_id') + ->where(Model::$tableName.'.activity_type',1) + ->where(Model::$tableName.'.status',1) + ->whereIn(OrderMainModel::$tableName.'.state',[4,5,10,11]); + + if($name){ + $orderGoodsActivity->where(Model::$tableName.'.name','like',"%$name%"); + } + if($marketId){ + $orderGoodsActivity->where('market_id',$marketId); + } + if($storeId){ + $orderGoodsActivity->where('store_id',$storeId); + } + if($startTime){ + $startTime = $startTime.' 00:00:00'; + + $orderGoodsActivity->where(Model::$tableName.'.created_at','>=',strtotime($startTime)); + } + if($endTime){ + $endTime = $endTime.' 23:59:59'; + + $orderGoodsActivity->where(Model::$tableName.'.created_at','<=',strtotime($endTime)); + } + + return $orderGoodsActivity; + } + + /** + * 获取总数 + */ + public function getCountData($params = []) + { + $selects = "SUM(lanzu_order_goods.number) as total,SUM((original_price-price)*number) as subsidy_total,FROM_UNIXTIME(lanzu_order_goods.created_at,'%Y-%m-%d') as dtime"; + $orderGoodsActivity = $this->getDataModel($selects,$params); + $total = $orderGoodsActivity->orderBy('dtime','asc')->groupBy('dtime')->get()->toArray(); + + return $total ?? []; + } + + /** + * 分市场获取 + */ + public function getMarketData($params = []) + { + $selects = "SUM(lanzu_order_goods.number) as total,SUM((original_price-price)*number) as subsidy_total,market_id"; + $orderGoodsActivity = $this->getDataModel($selects,$params); + $total = $orderGoodsActivity->groupBy('market_id')->get()->toArray(); + + return $total ?? []; + } +} diff --git a/app/Admin/Widgets/Charts/OrderGoodsActivityCountChart.php b/app/Admin/Widgets/Charts/OrderGoodsActivityCountChart.php index c7e9147..61bbe69 100644 --- a/app/Admin/Widgets/Charts/OrderGoodsActivityCountChart.php +++ b/app/Admin/Widgets/Charts/OrderGoodsActivityCountChart.php @@ -38,6 +38,8 @@ class OrderGoodsActivityCountChart extends Line } $subsidyTotal += $value['subsidy_total']; } + $this->data = array_reverse($this->data); + $this->categories = array_reverse($this->categories); $this->total['subsidy_total'] = $subsidyTotal; } diff --git a/app/Admin/Widgets/Charts/OrderGoodsActivityTotalChart.php b/app/Admin/Widgets/Charts/OrderGoodsActivityTotalChart.php index ad664c1..81824d9 100644 --- a/app/Admin/Widgets/Charts/OrderGoodsActivityTotalChart.php +++ b/app/Admin/Widgets/Charts/OrderGoodsActivityTotalChart.php @@ -36,6 +36,8 @@ class OrderGoodsActivityTotalChart extends Bar } $total += $value['total']; } + $this->data = array_reverse($this->data); + $this->categories = array_reverse($this->categories); $this->total['number_total'] = $total; } diff --git a/app/Admin/routes.php b/app/Admin/routes.php index f158aa4..735a31d 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -92,5 +92,8 @@ Route::group([ // 活动商品统计 $router->any('/goods_activity_report', 'v3\GoodsActivityReportController@index'); $router->any('/goods_activity_export', 'v3\GoodsActivityReportController@export'); + //普通商品统计 + $router->resource('/goods_report', 'v3\GoodsReportController'); + $router->any('/goods_report_export', 'v3\GoodsReportController@export'); }); diff --git a/app/Models/ImsCjdcOrder.php b/app/Models/ImsCjdcOrder.php index 9888fea..e2794ef 100644 --- a/app/Models/ImsCjdcOrder.php +++ b/app/Models/ImsCjdcOrder.php @@ -12,6 +12,8 @@ class ImsCjdcOrder extends Model protected $table = 'lanzu_order as order'; public $timestamps = false; + public static $tableName = 'lanzu_order'; + public function user() { return $this->hasOne('\App\Models\ImsCjdcUser','id','user_id'); diff --git a/app/Models/ImsCjdcOrderMain.php b/app/Models/ImsCjdcOrderMain.php index 65a2c89..9bc5744 100644 --- a/app/Models/ImsCjdcOrderMain.php +++ b/app/Models/ImsCjdcOrderMain.php @@ -50,6 +50,8 @@ class ImsCjdcOrderMain extends Model protected $table = 'lanzu_order_main'; public $timestamps = false; + public static $tableName = 'lanzu_order_main'; + public function imsCjdcUser() { return $this->hasOne('\App\Models\ImsCjdcUser', 'id', 'user_id'); diff --git a/app/Models/LanzuOrderGoods.php b/app/Models/LanzuOrderGoods.php index 8e262fc..df1455e 100644 --- a/app/Models/LanzuOrderGoods.php +++ b/app/Models/LanzuOrderGoods.php @@ -14,6 +14,8 @@ class LanzuOrderGoods extends Model protected $table = 'lanzu_order_goods'; protected $dateFormat = 'U'; + public static $tableName = 'lanzu_order_goods'; + public function goods() { return $this->belongsTo('\App\Models\LanzuGoods','goods_id','id'); diff --git a/resources/lang/zh-CN/goods-report.php b/resources/lang/zh-CN/goods-report.php new file mode 100644 index 0000000..c8b1519 --- /dev/null +++ b/resources/lang/zh-CN/goods-report.php @@ -0,0 +1,21 @@ + [ + 'GoodsReport' => '普通商品统计报表', + 'goods_report' => '普通商品统计报表', + ], + 'fields' => [ + 'goods_id' => '商品ID', + 'name' => '统计名称', + 'cover_img' => '封面图', + 'market_id' => '市场', + 'store_id' => '店铺', + 'price' => '售价', + 'original_price' => '原价', + 'number' => '数量', + 'created_at' => '下单时间', + 'global_order_id' => '主订单号', + ], + 'options' => [ + ], +];