|
|
@@ -0,0 +1,240 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Module\Mex\AdminControllers;
|
|
|
+
|
|
|
+use App\Module\Fund\Enums\FUND_CURRENCY_TYPE;
|
|
|
+use App\Module\Mex\AdminControllers\Helper\GridHelper;
|
|
|
+use App\Module\Mex\Metrics\PriceTrendChart;
|
|
|
+use App\Module\Mex\Repositories\MexDailyPriceTrendRepository;
|
|
|
+use App\Module\Mex\Service\MexDailyPriceTrendService;
|
|
|
+use Spatie\RouteAttributes\Attributes\Get;
|
|
|
+use Spatie\RouteAttributes\Attributes\Resource;
|
|
|
+use UCore\DcatAdmin\AdminController;
|
|
|
+use Dcat\Admin\Grid;
|
|
|
+use Dcat\Admin\Show;
|
|
|
+use Dcat\Admin\Layout\Content;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 农贸市场每日价格趋势管理
|
|
|
+ *
|
|
|
+ * 路由:/admin/mex-daily-price-trends
|
|
|
+ */
|
|
|
+#[Resource('mex-daily-price-trends', names: 'dcat.admin.mex-daily-price-trends')]
|
|
|
+class MexDailyPriceTrendController extends AdminController
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * 页面标题
|
|
|
+ */
|
|
|
+ protected $title = '农贸市场每日价格趋势';
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 列表页面
|
|
|
+ */
|
|
|
+ public function index(Content $content)
|
|
|
+ {
|
|
|
+ return $content
|
|
|
+ ->title('农贸市场每日价格趋势')
|
|
|
+ ->description('价格趋势分析与数据管理')
|
|
|
+ ->row(function ($row) {
|
|
|
+ // 添加价格趋势图表
|
|
|
+ $chart = new PriceTrendChart();
|
|
|
+ $row->column(12, $chart);
|
|
|
+ })
|
|
|
+ ->body($this->grid());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 数据表格
|
|
|
+ */
|
|
|
+ protected function grid()
|
|
|
+ {
|
|
|
+ return Grid::make(new MexDailyPriceTrendRepository(['item']), function (Grid $grid) {
|
|
|
+ $helper = new GridHelper($grid, $this);
|
|
|
+
|
|
|
+ $grid->column('id', 'ID')->sortable();
|
|
|
+ $grid->column('item_id', '商品ID')->link(function ($value) {
|
|
|
+ return admin_url("game-items/{$value}");
|
|
|
+ });
|
|
|
+ $grid->column('item.name', '商品名称');
|
|
|
+ $grid->column('currency_type', '币种')->display(function ($value) {
|
|
|
+ if (is_string($value)) {
|
|
|
+ return FUND_CURRENCY_TYPE::from($value)->name;
|
|
|
+ }
|
|
|
+ return $value->name;
|
|
|
+ });
|
|
|
+ $grid->column('trade_date', '交易日期')->sortable();
|
|
|
+
|
|
|
+ // 价格信息
|
|
|
+ $grid->column('open_price', '开盘价')->display(function ($value) {
|
|
|
+ return $value ? number_format($value, 5) : '-';
|
|
|
+ });
|
|
|
+ $grid->column('close_price', '收盘价')->display(function ($value) {
|
|
|
+ return $value ? number_format($value, 5) : '-';
|
|
|
+ });
|
|
|
+ $grid->column('high_price', '最高价')->display(function ($value) {
|
|
|
+ return $value ? number_format($value, 5) : '-';
|
|
|
+ });
|
|
|
+ $grid->column('low_price', '最低价')->display(function ($value) {
|
|
|
+ return $value ? number_format($value, 5) : '-';
|
|
|
+ });
|
|
|
+
|
|
|
+ // 价格变化
|
|
|
+ $grid->column('price_change_percent', '涨跌幅')->display(function ($value) {
|
|
|
+ if ($value === null) return '-';
|
|
|
+ $color = $value > 0 ? 'success' : ($value < 0 ? 'danger' : 'secondary');
|
|
|
+ $symbol = $value > 0 ? '+' : '';
|
|
|
+ return "<span class='text-{$color}'>{$symbol}" . number_format($value, 2) . "%</span>";
|
|
|
+ });
|
|
|
+
|
|
|
+ // 交易统计
|
|
|
+ $grid->column('total_volume', '成交量')->sortable();
|
|
|
+ $grid->column('total_amount', '成交额')->display(function ($value) {
|
|
|
+ return number_format($value, 5);
|
|
|
+ })->sortable();
|
|
|
+ $grid->column('transaction_count', '成交笔数');
|
|
|
+
|
|
|
+ // 波动率
|
|
|
+ $grid->column('volatility', '波动率')->display(function ($value) {
|
|
|
+ if ($value === null) return '-';
|
|
|
+ $level = $this->volatility_level;
|
|
|
+ $color = match($level) {
|
|
|
+ '低波动' => 'success',
|
|
|
+ '中等波动' => 'warning',
|
|
|
+ '高波动' => 'danger',
|
|
|
+ '极高波动' => 'dark',
|
|
|
+ default => 'secondary'
|
|
|
+ };
|
|
|
+ return "<span class='badge badge-{$color}'>{$level} (" . number_format($value, 2) . "%)</span>";
|
|
|
+ });
|
|
|
+
|
|
|
+ $helper->columnUpdatedAt();
|
|
|
+
|
|
|
+ // 筛选器
|
|
|
+ $grid->filter(function (Grid\Filter $filter) {
|
|
|
+ $filter->equal('item_id', '商品ID');
|
|
|
+ $filter->equal('currency_type', '币种')->select([
|
|
|
+ FUND_CURRENCY_TYPE::ZUANSHI->value => '钻石',
|
|
|
+ FUND_CURRENCY_TYPE::JINBI->value => '金币',
|
|
|
+ ]);
|
|
|
+ $filter->between('trade_date', '交易日期')->date();
|
|
|
+ $filter->between('total_volume', '成交量范围');
|
|
|
+ $filter->between('total_amount', '成交额范围');
|
|
|
+ $filter->between('price_change_percent', '涨跌幅范围');
|
|
|
+ });
|
|
|
+
|
|
|
+ // 默认排序
|
|
|
+ $grid->model()->orderBy('trade_date', 'desc')->orderBy('item_id');
|
|
|
+
|
|
|
+ // 禁用新增、编辑、删除操作
|
|
|
+ $grid->disableCreateButton();
|
|
|
+ $grid->disableActions();
|
|
|
+ $grid->disableBatchActions();
|
|
|
+
|
|
|
+ // 添加工具栏按钮
|
|
|
+ $grid->tools(function (Grid\Tools $tools) {
|
|
|
+ $tools->append('<a href="' . admin_url('mex-daily-price-trends/generate') . '" class="btn btn-primary btn-sm">
|
|
|
+ <i class="fa fa-refresh"></i> 生成趋势数据
|
|
|
+ </a>');
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 详情页面
|
|
|
+ */
|
|
|
+ protected function detail($id)
|
|
|
+ {
|
|
|
+ return Show::make($id, new MexDailyPriceTrendRepository(['item']), function (Show $show) {
|
|
|
+ $show->field('id', 'ID');
|
|
|
+ $show->field('item_id', '商品ID');
|
|
|
+ $show->field('item.name', '商品名称');
|
|
|
+ $show->field('currency_type', '币种')->as(function ($value) {
|
|
|
+ if (is_string($value)) {
|
|
|
+ return FUND_CURRENCY_TYPE::from($value)->name;
|
|
|
+ }
|
|
|
+ return $value->name;
|
|
|
+ });
|
|
|
+ $show->field('trade_date', '交易日期');
|
|
|
+
|
|
|
+ $show->divider('价格信息');
|
|
|
+
|
|
|
+ $show->field('open_price', '开盘价')->as(function ($value) {
|
|
|
+ return $value ? number_format($value, 5) : '-';
|
|
|
+ });
|
|
|
+ $show->field('close_price', '收盘价')->as(function ($value) {
|
|
|
+ return $value ? number_format($value, 5) : '-';
|
|
|
+ });
|
|
|
+ $show->field('high_price', '最高价')->as(function ($value) {
|
|
|
+ return $value ? number_format($value, 5) : '-';
|
|
|
+ });
|
|
|
+ $show->field('low_price', '最低价')->as(function ($value) {
|
|
|
+ return $value ? number_format($value, 5) : '-';
|
|
|
+ });
|
|
|
+ $show->field('avg_price', '平均价')->as(function ($value) {
|
|
|
+ return $value ? number_format($value, 5) : '-';
|
|
|
+ });
|
|
|
+
|
|
|
+ $show->divider('价格变化');
|
|
|
+
|
|
|
+ $show->field('price_change', '价格变化')->as(function ($value) {
|
|
|
+ return $value ? number_format($value, 5) : '-';
|
|
|
+ });
|
|
|
+ $show->field('price_change_percent', '涨跌幅')->as(function ($value) {
|
|
|
+ return $value ? number_format($value, 2) . '%' : '-';
|
|
|
+ });
|
|
|
+ $show->field('volatility', '波动率')->as(function ($value) {
|
|
|
+ return $value ? number_format($value, 2) . '%' : '-';
|
|
|
+ });
|
|
|
+
|
|
|
+ $show->divider('交易统计');
|
|
|
+
|
|
|
+ $show->field('total_volume', '总成交量');
|
|
|
+ $show->field('total_amount', '总成交额')->as(function ($value) {
|
|
|
+ return number_format($value, 5);
|
|
|
+ });
|
|
|
+ $show->field('transaction_count', '成交笔数');
|
|
|
+ $show->field('buy_volume', '买入量');
|
|
|
+ $show->field('sell_volume', '卖出量');
|
|
|
+ $show->field('buy_amount', '买入额')->as(function ($value) {
|
|
|
+ return number_format($value, 5);
|
|
|
+ });
|
|
|
+ $show->field('sell_amount', '卖出额')->as(function ($value) {
|
|
|
+ return number_format($value, 5);
|
|
|
+ });
|
|
|
+
|
|
|
+ $show->divider('管理员操作');
|
|
|
+
|
|
|
+ $show->field('admin_inject_volume', '管理员注入量');
|
|
|
+ $show->field('admin_recycle_volume', '管理员回收量');
|
|
|
+ $show->field('admin_inject_amount', '管理员注入额')->as(function ($value) {
|
|
|
+ return number_format($value, 5);
|
|
|
+ });
|
|
|
+ $show->field('admin_recycle_amount', '管理员回收额')->as(function ($value) {
|
|
|
+ return number_format($value, 5);
|
|
|
+ });
|
|
|
+
|
|
|
+ $show->field('created_at', '创建时间');
|
|
|
+ $show->field('updated_at', '更新时间');
|
|
|
+
|
|
|
+ // 禁用编辑和删除按钮
|
|
|
+ $show->disableEditButton();
|
|
|
+ $show->disableDeleteButton();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成趋势数据
|
|
|
+ */
|
|
|
+ #[Get('mex-daily-price-trends/generate', name: 'admin.mex-daily-price-trends.generate')]
|
|
|
+ public function generate()
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // 调用服务生成今日价格趋势数据
|
|
|
+ $trends = MexDailyPriceTrendService::generateTodayTrends();
|
|
|
+
|
|
|
+ return redirect()->back()->with('success', "价格趋势数据生成成功!共生成 {$trends->count()} 条记录。");
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ return redirect()->back()->with('error', '生成失败:' . $e->getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|