diff --git a/.gitignore b/.gitignore index c407190..d8a8286 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /public/hot /public/storage /storage/*.key +/storage/ /vendor .env .env.backup diff --git a/app/Admin/Actions/LinkCreateAddress.php b/app/Admin/Actions/LinkCreateAddress.php new file mode 100644 index 0000000..3ee916a --- /dev/null +++ b/app/Admin/Actions/LinkCreateAddress.php @@ -0,0 +1,20 @@ +row->id); + } + +} \ No newline at end of file diff --git a/app/Admin/Actions/LinkStockOrderDeliver.php b/app/Admin/Actions/LinkStockOrderDeliver.php new file mode 100644 index 0000000..bd5f1ec --- /dev/null +++ b/app/Admin/Actions/LinkStockOrderDeliver.php @@ -0,0 +1,20 @@ +row->user->id); + } + +} \ No newline at end of file diff --git a/app/Admin/Actions/LinkVipOrderRefund.php b/app/Admin/Actions/LinkVipOrderRefund.php new file mode 100644 index 0000000..eecadb1 --- /dev/null +++ b/app/Admin/Actions/LinkVipOrderRefund.php @@ -0,0 +1,20 @@ +row->user->username); + } + +} \ No newline at end of file diff --git a/app/Admin/Controllers/HomeController.php b/app/Admin/Controllers/HomeController.php index 65b757d..263e8b2 100644 --- a/app/Admin/Controllers/HomeController.php +++ b/app/Admin/Controllers/HomeController.php @@ -3,44 +3,244 @@ namespace App\Admin\Controllers; use App\Http\Controllers\Controller; +use Encore\Admin\Facades\Admin; use Encore\Admin\Layout\Column; use Encore\Admin\Layout\Content; use Encore\Admin\Layout\Row; +use Encore\Admin\Widgets\InfoBox; +use Illuminate\Support\Facades\Artisan; +use Modules\Mall\Models\Order; +use Modules\Mall\Models\OrderItem; +use Modules\User\Models\Identity; +use Modules\User\Models\User; +use Modules\User\Models\UserStock; class HomeController extends Controller { + public $content; + /** * Notes : 数据看板 * * @Date : 2021/3/10 5:12 下午 - * @Author : + * @Author : < Jason.C > * @param Content $content * @return Content */ - public function index(Content $content): Content + public function index(Content $content) { - if (config('app.debug')) { - return $content - ->title(__('admin.menu_titles.dashboard')) - ->description('Description...') - ->row(Dashboard::title()) - ->row(function (Row $row) { - $row->column(4, function (Column $column) { - $column->append(Dashboard::environment()); - }); - - $row->column(4, function (Column $column) { - $column->append(Dashboard::dependencies()); - }); - - $row->column(4, function (Column $column) { - $column->append(Dashboard::extensions()); - }); - }); - } else { - return $content - ->title(__('admin.menu_titles.dashboard')) - ->description('Description...'); - } + $this->content = $content->title('数据看板')->description('Description...'); + $this->getUserData(); + $this->getUserStockData(); + $this->getUserStockOrderData(); + return $this->content; } + + /** + * Notes: 获取用户数据 + * + * @Author: 玄尘 + * @Date : 2021/11/17 11:24 + */ + public function getUserData() + { + $this->content->row($this->setDivider('用户统计')); + + $users = [ + 'all' => [ + 'name' => '用户总数', + 'color' => 'blue', + 'count' => User::count() + ], + 'free_vip' => [ + 'name' => '免费会员', + 'color' => 'green', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->FreeVip(); + })->count() + ], + 'yk' => [ + 'name' => '月卡用户数', + 'color' => 'red', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->Yk(); + })->count() + ], + 'jk' => [ + 'name' => '季卡用户数', + 'color' => 'red', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->Jk(); + })->count() + ], + 'nk' => [ + 'name' => '年卡用户数', + 'color' => 'yellow', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->Nk(); + })->count(), + ], + ]; + + $this->content->row(function (Row $row) use ($users) { + foreach ($users as $user) { + $row->column(2, function (Column $column) use ($user) { + $column->append(new InfoBox( + $user['name'], + 'users', + $user['color'], + '/admin/users', + $user['count'], + )); + + }); + } + }); + + return $this->content; + } + + /** + * Notes: 用户水数量 + * + * @Author: 玄尘 + * @Date: 2022/9/1 13:35 + * @return mixed + */ + public function getUserStockData() + { + $this->content->row($this->setDivider('会员水库存数')); + + $all = UserStock::query()->sum('stock'); + $holds = UserStock::query()->sum('hold'); + $sy = bcsub($all, $holds); + + $users = [ + 'all' => [ + 'name' => '总数', + 'color' => 'blue', + 'count' => UserStock::query()->sum('stock') + ], + 'stock' => [ + 'name' => '已提货数', + 'color' => 'green', + 'count' => UserStock::query()->sum('hold') + ], + 'sy' => [ + 'name' => '待提货数', + 'color' => 'green', + 'count' => $sy + ], + ]; + + $this->content->row(function (Row $row) use ($users) { + foreach ($users as $user) { + $row->column(2, function (Column $column) use ($user) { + $column->append(new InfoBox( + $user['name'], + 'goods', + $user['color'], + '/admin/stocks', + $user['count'], + )); + + }); + } + }); + + return $this->content; + } + + /** + * Notes: 提货订单数量 + * + * @Author: 玄尘 + * @Date: 2022/9/1 13:51 + */ + public function getUserStockOrderData() + { + $this->content->row($this->setDivider('会员提货订单')); + $users = [ + 'all' => [ + 'name' => '订单总数', + 'color' => 'blue', + 'count' => Order::query()->where('type', Order::TYPE_SAMPLE)->count() + ], + 'deliver' => [ + 'name' => '待发货', + 'color' => 'green', + 'count' => Order::query() + ->where('type', Order::TYPE_SAMPLE) + ->paid() + ->count() + ], + 'deliverd' => [ + 'name' => '已发货', + 'color' => 'green', + 'count' => Order::query() + ->where('type', Order::TYPE_SAMPLE) + ->whereIn('state', [ + Order::STATUS_DELIVERED, + ]) + ->count(), + ], + 'signed' => [ + 'name' => '已签收', + 'color' => 'green', + 'count' => Order::query() + ->where('type', Order::TYPE_SAMPLE) + ->whereIn('state', [ + Order::STATUS_SIGNED, + ]) + ->count() + ], + ]; + + $this->content->row(function (Row $row) use ($users) { + foreach ($users as $user) { + $row->column(2, function (Column $column) use ($user) { + $column->append(new InfoBox( + $user['name'], + 'goods', + $user['color'], + '/admin/stocks', + $user['count'], + )); + + }); + } + }); + + return $this->content; + } + + /** + * Notes : 清理模型缓存 + * + * @Date : 2021/6/8 10:51 上午 + * @Author : < Jason.C > + * @return string + */ + public function cleanCache(): string + { + Artisan::call('modelCache:clear'); + + return '缓存清理成功'; + } + + public function setDivider($title) + { + return << + + {$title} + + +HTML; + } + } diff --git a/app/Admin/Controllers/Material/IndexController.php b/app/Admin/Controllers/Material/IndexController.php new file mode 100644 index 0000000..ac6454e --- /dev/null +++ b/app/Admin/Controllers/Material/IndexController.php @@ -0,0 +1,56 @@ +column('id', '编号'); + $grid->column('title', '名称'); + $grid->column('地址')->display(function () { + return $this->cover_url; + }); + $grid->column('created_at', '创建时间'); + + return $grid; + } + + /** + * Make a form builder. + * + * @return Form + */ + protected function form(): Form + { + $form = new Form(new Material()); + $form->text('title', '名称'); + $form->image('cover', '图片') + ->move('materials/'.date('Y/m/d')) + ->removable() + ->required(); + + return $form; + } + +} diff --git a/app/Admin/Controllers/Platform/DashboardController.php b/app/Admin/Controllers/Platform/DashboardController.php new file mode 100644 index 0000000..d42ba28 --- /dev/null +++ b/app/Admin/Controllers/Platform/DashboardController.php @@ -0,0 +1,205 @@ +content = $content->title('数据看板')->description('Description...'); + $this->getVipUserData(); + $this->getUserStockData(); + return $this->content; + + } + + /** + * Notes: 获取用户数据 + * + * @Author: 玄尘 + * @Date : 2021/11/17 11:24 + */ + public function getVipUserData(): Content + { + $this->content->row($this->setDivider('会员统计')); + $users = [ + 'all' => [ + 'name' => '总会员量', + 'color' => 'blue', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->where('id', '>', 1); + })->count() + ], + 'free_vip' => [ + 'name' => '免费会员', + 'color' => 'green', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->FreeVip(); + })->count() + ], + 'yk' => [ + 'name' => '月卡用户数', + 'color' => 'red', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->Yk(); + })->count() + ], + 'jk' => [ + 'name' => '季卡用户数', + 'color' => 'red', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->Jk(); + })->count() + ], + 'nk' => [ + 'name' => '年卡用户数', + 'color' => 'yellow', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->Nk(); + })->count(), + ], + 'onlone' => [ + 'name' => '在线会员数', + 'color' => 'red', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->where('id', '>', 2); + }) + ->where('status', User::STATUS_INIT) + ->count(), + ], + 'refund' => [ + 'name' => '退费会员数', + 'color' => 'maroon', + 'count' => User::query() + ->whereHas('identities', function ($q) { + $q->where('id', '>', 2); + }) + ->where('status', User::STATUS_REFUND) + ->count(), + ], + ]; + + $this->content->row(function (Row $row) use ($users) { + foreach ($users as $user) { + $row->column(2, function (Column $column) use ($user) { + $column->append(new InfoBox( + $user['name'], + 'users', + $user['color'], + '/admin/platform/vips', + $user['count'], + )); + + }); + } + }); + + return $this->content; + } + + + /** + * Notes: 用户水数量 + * + * @Author: 玄尘 + * @Date: 2022/9/1 13:35 + * @return mixed + */ + public function getUserStockData() + { + $this->content->row($this->setDivider('会员库存数')); + + $all = UserStock::query()->sum('stock'); + $holds = UserStock::query()->sum('hold'); + $sy = bcsub($all, $holds); + + $users = [ + 'all' => [ + 'name' => '累计总箱数', + 'color' => 'blue', + 'count' => $all + ], + 'stock' => [ + 'name' => '累计提货数', + 'color' => 'green', + 'count' => $holds + ], + 'sy' => [ + 'name' => '累计剩余', + 'color' => 'green', + 'count' => $sy + ], + 'online' => [ + 'name' => '线上发货', + 'color' => 'green', + 'count' => OrderItem::query() + ->whereHas('order', function ($q) { + $q->whereIn('state', [ + Order::STATUS_PAID, + Order::STATUS_DELIVERED, + Order::STATUS_SIGNED, + ])->where('channel', Order::CHANNEL_USER); + }) + ->sum('qty') + ], + 'offline' => [ + 'name' => '线下发货', + 'color' => 'green', + 'count' => OrderItem::query() + ->whereHas('order', function ($q) { + $q->whereIn('state', [ + Order::STATUS_PAID, + Order::STATUS_DELIVERED, + Order::STATUS_SIGNED, + ])->where('channel', Order::CHANNEL_SYSTEM); + }) + ->sum('qty') + ], + ]; + + $this->content->row(function (Row $row) use ($users) { + foreach ($users as $user) { + $row->column(2, function (Column $column) use ($user) { + $column->append(new InfoBox( + $user['name'], + 'goods', + $user['color'], + '/admin/users/stocks', + $user['count'], + )); + + }); + } + }); + + return $this->content; + } + + public function setDivider($title) + { + return << + + {$title} + + +HTML; + } + +} \ No newline at end of file diff --git a/app/Admin/Controllers/Platform/VipController.php b/app/Admin/Controllers/Platform/VipController.php new file mode 100644 index 0000000..bbdb19f --- /dev/null +++ b/app/Admin/Controllers/Platform/VipController.php @@ -0,0 +1,255 @@ + + * @return Grid + */ + public function grid(): Grid + { + $grid = new Grid(new User()); + + $grid->actions(function (Grid\Displayers\Actions $actions) { + $actions->disableEdit(); + $actions->disableDelete(); + $actions->disableView(); + if ($actions->row->status == User::STATUS_INIT) { + $actions->add(new UserStatusRefund()); + } + if ($actions->row->status == User::STATUS_REFUND) { + $actions->add(new UserStatusInit()); + } + + $actions->add(new JoinIdentity()); + $actions->add(new AddUserRemark()); + $actions->add(new LinkCreateAddress()); + + }); + + $grid->quickSearch('username')->placeholder('快速搜索用户名'); + + $grid->filter(function (Grid\Filter $filter) { + $filter->column(1 / 3, function (Grid\Filter $filter) { + $filter->like('username', '用户名'); + }); + + $filter->column(1 / 3, function (Grid\Filter $filter) { + $filter->like('info.nickname', '用户昵称'); + }); + $filter->column(1 / 3, function (Grid\Filter $filter) { + $filter->equal('identities.id', '身份') + ->select(Identity::query()->where('id', '>', 1)->pluck('name', 'id')); + }); + }); + + $grid->model() + ->whereHas('identities', function ($q) { + $q->where('id', '>', 1); + }) + ->withCount(['addresses', 'logs']) + ->with(['info', 'parent', 'identities', 'addresses', 'vipOrders', 'userStock', 'logs']); + + //序号 姓名 手机号 会员类型 会员编号 缴费金额 加入时间 状态(正常,退费) 用箱数 提货箱数 剩余箱数 + $grid->column('id', '序号'); + $grid->column('username', '手机号'); + $grid->column('identities', '会员类型') + ->display(function () { + $data = []; + foreach ($this->identities as $identity) { + $data[] = $identity->name; + } + return $data; + }) + ->label(); + $grid->column('serial', '会员编号') + ->display(function () { + $data = []; + foreach ($this->identities as $identity) { + $data[] = $identity->serial_prefix.$identity->getOriginal('pivot_serial'); + } + return $data; + }) + ->label(); + + $grid->column('price', '缴费金额') + ->display(function () { + return $this->getOpenVipPrices(); + }) + ->label(); + + $grid->column('created_at', '加入时间'); + $grid->column('status', '状态') + ->using(User::STATUS) + ->label(); + $grid->column('userStock.stock', '总箱数'); + $grid->column('userStock.hold', '提货箱数'); + $grid->column('userStock.residue', '剩余箱数'); + $grid->column('addresses_count', '收货地址') + ->link(function () { + return route('admin.mall.addresses.index', ['user_id' => $this->id]); + }, '_self'); + $grid->column('logs_count', '备注') + ->modal('备注信息', UserLog::class); + + $grid->disableExport(false); + $grid->export(function ($export) { + $export->column('identities', function ($value, $original) { + return strip_tags($value); + }); + $export->column('serial', function ($value, $original) { + return strip_tags($value); + }); + $export->column('price', function ($value, $original) { + return strip_tags($value); + }); + $export->column('status', function ($value, $original) { + return strip_tags($value); + }); + +// $export->column('use_way', function ($value, $original) { +// return strip_tags($value); +// }); +// $export->column('所属用户', function ($value, $original) { +// return iconv('gb2312//ignore', 'utf-8', +// iconv('utf-8', 'gb2312//ignore', strip_tags(str_replace(" ", " ", $value)))); +// }); +// +// $export->column('couponGrant.code', function ($value, $original) { +// return $value."\n"; +// }); + + $export->except(['addresses_count', 'logs_count']); + + $export->filename($this->title.date("YmdHis")); + }); + + return $grid; + } + + /** + * Notes : 编辑表单 + * + * @Date : 2021/7/15 5:09 下午 + * @Author : + * @return Form + * @throws Exception + */ + public function form(): Form + { +// if (! config('user.create_user_by_admin')) { +// throw new Exception('不运允许操作用户'); +// } + + Admin::script(" $(document.body).append(`