Files
laralog/resources/views/filament/pages/plugins.blade.php
T
ak e06e7c4300 feat: 商城付费购买流 + 市场契约
- MarketPackage 模型/迁移:市场商品作为可购买实体(payable),复用 Payment 订单
- MarketPurchaseService:购买创建订单、已购判断、免费/付费门槛校验
- payment.paid 监听(核心注册,仅支付插件启用时)标记商品已购
- 市场契约:条目含 name/type/price(分)/download_url;插件市场 Tab 只显示 plugin、主题市场 Tab 只显示 theme;付费商品显示「购买」按钮与「已购买」徽章,未购买无法安装
- 新增主题市场 Tab(原仅插件页有市场)
- 测试:购买/沙箱支付标记已购/重复购买/安装门槛/免费条目/支付插件禁用
2026-08-12 01:34:04 +08:00

99 lines
6.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<x-filament-panels::page>
<x-filament::section heading="已安装插件">
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:1rem">
@forelse($this->plugins as $plugin)
<x-filament::section :compact="true">
<div class="flex flex-col">
<div class="flex items-start justify-between gap-3">
<x-filament::icon icon="heroicon-o-puzzle-piece" class="h-8 w-8 text-primary-600" />
@if($plugin['enabled'])
<x-filament::badge color="success">已启用</x-filament::badge>
@else
<x-filament::badge color="gray">已停用</x-filament::badge>
@endif
</div>
<h3 class="mt-3 text-base font-semibold">{{ $plugin['title'] }}</h3>
<p class="mt-1 flex-1 text-sm text-gray-500 dark:text-gray-400">{{ $plugin['description'] }}</p>
<p class="mt-2 text-xs text-gray-400">v{{ $plugin['version'] }} · {{ $plugin['vendor'] }}.{{ $plugin['name'] }}</p>
@if(! empty($plugin['dependencies']))
<div class="mt-2 flex flex-wrap items-center gap-1">
<span class="text-xs text-gray-400">依赖:</span>
@foreach($plugin['dependencies'] as $dep)
<x-filament::badge :color="$dep['ok'] ? 'success' : 'danger'" size="xs">
{{ $dep['title'] }}@if(! $dep['ok']){{ $dep['reason'] }}@endif
</x-filament::badge>
@endforeach
</div>
@endif
<div class="mt-4 flex flex-wrap gap-2">
@if($plugin['enabled'])
<x-filament::button size="sm" color="gray" wire:click="disablePlugin('{{ $plugin['key'] }}')">停用</x-filament::button>
@elseif(empty($plugin['dependency_errors']))
<x-filament::button size="sm" color="success" wire:click="enablePlugin('{{ $plugin['key'] }}')">启用</x-filament::button>
@else
<x-filament::badge color="warning">依赖未满足,无法启用</x-filament::badge>
@endif
@if(! in_array($plugin['key'], config('plugins.enabled', []), true))
<x-filament::button size="sm" color="danger" wire:click="uninstallPlugin('{{ $plugin['key'] }}')" wire:confirm="确定卸载该插件?">卸载</x-filament::button>
@endif
</div>
</div>
</x-filament::section>
@empty
<p class="text-sm text-gray-500">暂无插件</p>
@endforelse
</div>
</x-filament::section>
<x-filament::section heading="安装插件(ZIP">
<form wire:submit="uploadZip" class="flex items-end gap-3">
<div class="flex-1">
<x-filament::input.wrapper>
<x-filament::input type="file" wire:model="zip" accept=".zip" />
</x-filament::input.wrapper>
@error('zip') <p class="mt-1 text-sm text-danger-600">{{ $message }}</p> @enderror
</div>
<x-filament::button type="submit" color="primary">安装</x-filament::button>
</form>
</x-filament::section>
<x-filament::section heading="插件市场" :description="config('market.url') ?: '未配置远程市场(config/market.php 的 MARKET_URL),仅支持本地 ZIP 安装'">
<div class="mb-4">
<x-filament::button color="gray" wire:click="loadMarket">刷新市场</x-filament::button>
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:1rem">
@forelse($marketItems as $index => $item)
@php $marketPaid = $item['price'] > 0; @endphp
<x-filament::section :compact="true">
<div class="flex flex-col">
<div class="flex items-start justify-between gap-3">
<x-filament::icon icon="heroicon-o-cloud-arrow-down" class="h-8 w-8 text-primary-600" />
@if($marketPaid)
<x-filament::badge color="warning">¥{{ number_format($item['price'] / 100, 2) }}</x-filament::badge>
@else
<x-filament::badge color="success">免费</x-filament::badge>
@endif
</div>
<h3 class="mt-3 text-base font-semibold">{{ $item['title'] ?? $item['name'] }}</h3>
<p class="mt-1 flex-1 text-sm text-gray-500 dark:text-gray-400">{{ $item['description'] ?? '' }}</p>
<p class="mt-2 text-xs text-gray-400">{{ $item['version'] ?? '' }} · {{ $item['author'] ?? '' }}</p>
<div class="mt-4 flex flex-wrap gap-2">
@if($marketPaid && ! $this->isMarketPurchased($index))
<x-filament::button size="sm" color="primary" wire:click="purchaseMarketItem({{ $index }})">购买</x-filament::button>
@elseif($marketPaid)
<x-filament::badge color="success">已购买</x-filament::badge>
@endif
<x-filament::button size="sm" color="gray" wire:click="installFromMarket({{ $index }})">安装</x-filament::button>
</div>
</div>
</x-filament::section>
@empty
<p class="text-sm text-gray-500">点击「刷新市场」拉取可用插件</p>
@endforelse
</div>
</x-filament::section>
</x-filament-panels::page>