1.完善了购买后的积分记录,如下:

具体修改文件:ziiven/flarum-decoration-store/src/Controller/DecorationStorePurchaseController.php
<?php
namespace Ziven\decorationStore\Controller;
use Ziven\decorationStore\Serializer\DecorationStorePurchaseSerializer;
use Ziven\decorationStore\Model\DecorationStore;
use Ziven\decorationStore\Model\DecorationStorePurchase;
use Ziven\decorationStore\Helpers\CommonHelper;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\Api\Controller\AbstractCreateController;
use Flarum\User\User;
use Flarum\Foundation\ValidationException;
use Flarum\Locale\Translator;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document;
use Illuminate\Support\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Mattoid\MoneyHistory\Event\MoneyHistoryEvent; // 增加引用
use Illuminate\Contracts\Events\Dispatcher; // 增加引用
class DecorationStorePurchaseController extends AbstractCreateController{
public $serializer = DecorationStorePurchaseSerializer::class;
protected $settings;
protected $translator;
protected $events; //增加
//修改为下面的 public function __construct(Translator $translator,SettingsRepositoryInterface $settings){
public function __construct(Translator $translator,SettingsRepositoryInterface $settings,Dispatcher $events){
$this->settings = $settings;
$this->translator = $translator;
$this->events = $events; //增加
}
protected function data(ServerRequestInterface $request, Document $document){
$requestData = $request->getParsedBody()['data']['attributes'];
$itemID = $requestData['itemID'];
$currentUserID = $request->getAttribute('actor')->id;
$errorMessage = "";
if(!isset($itemID)){
$errorMessage = 'ziven-decoration-store.forum.purchase-error';
}else{
$itemData = DecorationStore::where(["isActivate"=>1,"id"=>$itemID])->first();
if(isset($itemData)){
$itemCount = 1;
$itemCost = $itemData->item_cost;
$itemDiscount = $itemData->item_discount;
$itemActualCost = (new CommonHelper)->getActualCost($itemData,$itemCount,"store");
$itemSold = $itemData->item_sold;
$itemAmount = $itemData->item_amount;
$itemType = $itemData->item_type;
$itemAvailableAmount = $itemAmount-$itemSold;
$itemPurchaseType = $itemData->purchase_type;
if($itemAvailableAmount>=$itemCount){
$currentUserData = User::find($currentUserID);
$currentUserMoneyRemain = $currentUserData->money-($itemActualCost*$itemCount);
if($currentUserMoneyRemain<0){
$errorMessage = 'ziven-decoration-store.forum.purchase-error-insufficient-fund';
}else{
$itemPurchaseCount = DecorationStorePurchase::where(["user_id"=>$currentUserID,"item_id"=>$itemID])->count();
if($itemPurchaseCount===0){
$itemData->item_sold+=$itemCount;
$itemData->save();
$currentUserData->money = $currentUserMoneyRemain;
$currentUserData->save();
$settingTimezone = (new CommonHelper)->getSettingTimezone();
$expiredDays = 0;
if($itemPurchaseType==="monthly"){
$expiredDays = 31;
}else if($itemPurchaseType==="yearly"){
$expiredDays = 365;
}
$itemPurchase = new DecorationStorePurchase();
$itemPurchase->item_id = $itemID;
$itemPurchase->user_id = $currentUserID;
$itemPurchase->item_type = $itemType;
$itemPurchase->item_count = $itemCount;
$itemPurchase->purchase_type = $itemPurchaseType;
$itemPurchase->purchase_cost = $itemCost;
$itemPurchase->purchase_discount = $itemDiscount;
$itemPurchase->expired_days = $expiredDays;
$itemPurchase->assigned_at = Carbon::now($settingTimezone);
$itemPurchase->save();
// 以下为新增内容
// 获取装饰品信息
$itemData = DecorationStore::where(["isActivate"=>1,"id"=>$itemID])->first();
//记录
$source = 'DECORATION_SUBSCRIBE';
$getDecorationTypeText = function($type) {
switch($type) {
case 'avatarFrame':
return '头像边框';
case 'profileBackground':
return '用户卡背景';
case 'usernameColor':
return '用户名颜色';
default:
return '未知类型';
}
};
$getPurchaseTypeText = function($type) {
switch($type) {
case 'monthly':
return '月度订阅';
case 'yearly':
return '年度订阅';
default:
return '一次性购买';
}
};
$sourceDesc = sprintf("购买装饰品:%s(%s,%s)",
$itemData->item_title,
$getDecorationTypeText($itemType),
$getPurchaseTypeText($itemPurchaseType)
);
if ($source && $sourceDesc) {
$this->events->dispatch(new MoneyHistoryEvent($currentUserData, -$itemActualCost, $source, $sourceDesc));
}
// 以上为新增内容
return $itemPurchase;
}else{
$errorMessage = 'ziven-decoration-store.forum.purchase-error-item-alreay-have';
}
}
}else{
$errorMessage = 'ziven-decoration-store.forum.sold-out';
}
}else{
$errorMessage = 'ziven-decoration-store.forum.purchase-error';
}
}
if($errorMessage!==""){
throw new ValidationException(['message' => $this->translator->trans($errorMessage)]);
}
}
}
**2.完善了订阅到期后不扣费的bug,并加入积分记录:
修改文件:ziiven/flarum-decoration-store/src/Console/DecorationStoreScheduleCommand.php
<?php
namespace Ziven\decorationStore\Console;
use Mattoid\MoneyHistory\Event\MoneyHistoryEvent; //新增
use Ziven\decorationStore\Model\DecorationStorePurchase;
use Ziven\decorationStore\Model\DecorationStore;
use Ziven\decorationStore\Notification\DecorationSubscriptionBlueprint;
use Ziven\decorationStore\Helpers\CommonHelper;
use Flarum\Console\AbstractCommand;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\User;
use Flarum\Notification\NotificationSyncer;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Support\Arr;
use Symfony\Contracts\Translation\TranslatorInterface;
class DecorationStoreScheduleCommand extends AbstractCommand{
protected $settings;
protected $translator;
protected $notifications;
private $events;
public function __construct(NotificationSyncer $notifications, SettingsRepositoryInterface $settings, TranslatorInterface $translator,Dispatcher $events){
parent::__construct();
$this->settings = $settings;
$this->translator = $translator;
$this->notifications = $notifications;
$this->events = $events;
}
protected function configure(){
$this->setName('decorationStore:checkDate')->setDescription('Check date');
}
protected function fire(){
$this->info('Sync starting...');
DecorationStore::where([["item_discount_days",">",0]])->decrement('item_discount_days');
$decorationStoreData = DecorationStore::where([["item_discount_days","=",0],["item_discount","!=",0]])->get();
foreach($decorationStoreData as $key => $value) {
$value->item_discount = 0;
$value->save();
}
DecorationStorePurchase::where([["expired_days",">",0]])->decrement('expired_days');
$decorationStorePurchaseData = DecorationStorePurchase::where([["expired_days","=",0],["purchase_type","!=","onetime"],["is_expired","=",0]])->get();
foreach($decorationStorePurchaseData as $key => $value) {
$itemType = $value->item_type;
$userID = $value->user_id;
$itemStatus = $value->item_status;
$purchaseCount = $value->item_count;
$purchaseCost = $value->purchase_cost;
$purchaseDiscount = $value->purchase_discount;
$purchaseType = $value->purchase_type;
$purchaseActualCost = (new CommonHelper)->getActualCost($value,$purchaseCount,"");
$isExpired = false;
$userData = User::find($userID);
$userMoney = $userData->money;
$userMoneyRemain = $userMoney-$purchaseActualCost;
// 获取装饰品信息
$itemID = $value->item_id;
$itemData = DecorationStore::where(["isActivate"=>1,"id"=>$itemID])->first();
$source = 'DECORATION_SUBSCRIBE';
// 类型转换
$getDecorationTypeText = function($type) {
switch($type) {
case 'avatarFrame':
return '头像边框';
case 'profileBackground':
return '用户卡背景';
case 'usernameColor':
return '用户名颜色';
default:
return '未知类型';
}
};
$getPurchaseTypeText = function($type) {
switch($type) {
case 'monthly':
return '月度订阅';
case 'yearly':
return '年度订阅';
default:
return '一次性购买';
}
};
//记录
$sourceDesc = sprintf("续费装饰品:%s(%s,%s)",
$itemData->item_title,
$getDecorationTypeText($itemType),
$getPurchaseTypeText($purchaseType) // 正确:使用 $purchaseType
);
//修改完成
if ($source && $sourceDesc) {
$this->events->dispatch(new MoneyHistoryEvent($userData, -$purchaseActualCost, $source, $sourceDesc));
}
if($userMoneyRemain<0){
if($itemType==="avatarFrame"){
$userData->decoration_avatarFrame = null;
}else if($itemType==="profileBackground"){
$userData->decoration_profileBackground = null;
}else if($itemType==="usernameColor"){
$userData->decoration_usernameColor = null;
}
$isExpired = true;
}else{
$userData->money = $userMoneyRemain;
if($purchaseType==="monthly"){
$value->expired_days = 31;
}else if($purchaseType==="yearly"){
$value->expired_days = 365;
}
}
$userData->save();
if($isExpired===true){
$value->item_status = 0;
$value->is_expired = 1;
}
$value->save();
$this->notifications->sync(new DecorationSubscriptionBlueprint($value),[$userData]);
}
$this->info('Sync done.');
}
}

一切都OK!