|
@@ -2,259 +2,176 @@
|
|
|
|
|
|
|
|
namespace Longyi\RewardPoints\Http\Controllers\Admin;
|
|
namespace Longyi\RewardPoints\Http\Controllers\Admin;
|
|
|
|
|
|
|
|
|
|
+use Exception;
|
|
|
|
|
+use Illuminate\Http\JsonResponse;
|
|
|
|
|
+use Illuminate\Http\RedirectResponse;
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Request;
|
|
|
-use Webkul\Admin\Http\Controllers\Controller;
|
|
|
|
|
|
|
+use Illuminate\Validation\Rule;
|
|
|
|
|
+use Illuminate\View\View;
|
|
|
use Longyi\RewardPoints\Models\RewardActiveRule;
|
|
use Longyi\RewardPoints\Models\RewardActiveRule;
|
|
|
use Longyi\RewardPoints\Repositories\RewardPointRepository;
|
|
use Longyi\RewardPoints\Repositories\RewardPointRepository;
|
|
|
|
|
+use Webkul\Admin\Http\Controllers\Controller;
|
|
|
|
|
+use Webkul\Core\Models\Channel;
|
|
|
|
|
+use Webkul\Customer\Models\CustomerGroup;
|
|
|
|
|
|
|
|
class RuleController extends Controller
|
|
class RuleController extends Controller
|
|
|
{
|
|
{
|
|
|
- protected $rewardPointRepository;
|
|
|
|
|
- protected $_config;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Transaction type mapping with complete configuration
|
|
|
|
|
+ */
|
|
|
|
|
+ private const TRANSACTION_TYPES = [
|
|
|
|
|
+ 1 => ['name' => 'Order', 'icon' => 'icon-shopping-cart', 'color' => 'blue'],
|
|
|
|
|
+ 2 => ['name' => 'Registration', 'icon' => 'icon-user', 'color' => 'green'],
|
|
|
|
|
+ 3 => ['name' => 'Product Review', 'icon' => 'icon-star', 'color' => 'yellow'],
|
|
|
|
|
+ 4 => ['name' => 'Daily Sign In', 'icon' => 'icon-calendar', 'color' => 'purple'],
|
|
|
|
|
+ 5 => ['name' => 'Referral', 'icon' => 'icon-share', 'color' => 'indigo'],
|
|
|
|
|
+ 6 => ['name' => 'Birthday', 'icon' => 'icon-gift', 'color' => 'pink'],
|
|
|
|
|
+ 7 => ['name' => 'Share', 'icon' => 'icon-share-alt', 'color' => 'orange'],
|
|
|
|
|
+ 8 => ['name' => 'Subscribe', 'icon' => 'icon-envelope', 'color' => 'orange'],
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Valid transaction type IDs
|
|
|
|
|
+ */
|
|
|
|
|
+ private const VALID_TRANSACTION_TYPES = [1, 2, 3, 4, 5, 6, 7, 8];
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Color classes mapping for transaction types
|
|
|
|
|
+ */
|
|
|
|
|
+ private const COLOR_CLASSES = [
|
|
|
|
|
+ 'blue' => 'bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300',
|
|
|
|
|
+ 'green' => 'bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300',
|
|
|
|
|
+ 'yellow' => 'bg-yellow-100 dark:bg-yellow-900 text-yellow-700 dark:text-yellow-300',
|
|
|
|
|
+ 'purple' => 'bg-purple-100 dark:bg-purple-900 text-purple-700 dark:text-purple-300',
|
|
|
|
|
+ 'indigo' => 'bg-indigo-100 dark:bg-indigo-900 text-indigo-700 dark:text-indigo-300',
|
|
|
|
|
+ 'pink' => 'bg-pink-100 dark:bg-pink-900 text-pink-700 dark:text-pink-300',
|
|
|
|
|
+ 'orange' => 'bg-orange-100 dark:bg-orange-900 text-orange-700 dark:text-orange-300',
|
|
|
|
|
+ 'gray' => 'bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ protected RewardPointRepository $rewardPointRepository;
|
|
|
|
|
+
|
|
|
|
|
+ protected array $_config;
|
|
|
|
|
|
|
|
public function __construct(RewardPointRepository $rewardPointRepository)
|
|
public function __construct(RewardPointRepository $rewardPointRepository)
|
|
|
{
|
|
{
|
|
|
$this->rewardPointRepository = $rewardPointRepository;
|
|
$this->rewardPointRepository = $rewardPointRepository;
|
|
|
- $this->_config = request('_config') ?: [];
|
|
|
|
|
|
|
+ $this->_config = request('_config', []);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Display a listing of reward rules
|
|
* Display a listing of reward rules
|
|
|
*/
|
|
*/
|
|
|
- public function index()
|
|
|
|
|
|
|
+ public function index(): View
|
|
|
{
|
|
{
|
|
|
- $rules = RewardActiveRule::orderBy('rule_id', 'desc')->paginate(15);
|
|
|
|
|
- $customerGroupsList = $this->getCustomerGroups(); // 获取群组列表
|
|
|
|
|
|
|
+ $rules = RewardActiveRule::query()
|
|
|
|
|
+ ->orderBy('rule_id', 'desc')
|
|
|
|
|
+ ->paginate(15);
|
|
|
|
|
|
|
|
- $view = isset($this->_config['view']) ? $this->_config['view'] : 'rewardpoints::admin.rules.index';
|
|
|
|
|
|
|
+ $customerGroupsList = $this->getCustomerGroups();
|
|
|
|
|
+ $transactionTypes = self::TRANSACTION_TYPES;
|
|
|
|
|
+ $colorClasses = self::COLOR_CLASSES;
|
|
|
|
|
+
|
|
|
|
|
+ $view = $this->_config['view'] ?? 'rewardpoints::admin.rules.index';
|
|
|
|
|
|
|
|
- return view($view, compact('rules', 'customerGroupsList'));
|
|
|
|
|
|
|
+ return view($view, compact('rules', 'customerGroupsList', 'transactionTypes', 'colorClasses'));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * Helper method to get transaction type name
|
|
|
|
|
|
|
+ * Show the form for creating a new reward rule
|
|
|
*/
|
|
*/
|
|
|
- protected function getTransactionTypeName($typeId)
|
|
|
|
|
|
|
+ public function create(): View
|
|
|
{
|
|
{
|
|
|
- $types = [
|
|
|
|
|
- 1 => 'Order',
|
|
|
|
|
- 2 => 'Registration',
|
|
|
|
|
- 3 => 'Product Review',
|
|
|
|
|
- 4 => 'Daily Sign In',
|
|
|
|
|
- 5 => 'Referral',
|
|
|
|
|
- 6 => 'Birthday',
|
|
|
|
|
- 7 => 'Share'
|
|
|
|
|
- ];
|
|
|
|
|
-
|
|
|
|
|
- return $types[$typeId] ?? 'Unknown';
|
|
|
|
|
|
|
+ $view = $this->_config['view'] ?? 'rewardpoints::admin.rules.create';
|
|
|
|
|
+
|
|
|
|
|
+ return view($view, [
|
|
|
|
|
+ 'transactionTypes' => self::TRANSACTION_TYPES,
|
|
|
|
|
+ 'storeViews' => $this->getStoreViews(),
|
|
|
|
|
+ 'customerGroups' => $this->getCustomerGroups(),
|
|
|
|
|
+ 'colorClasses' => self::COLOR_CLASSES,
|
|
|
|
|
+ ]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
- * Show the form for creating a new reward rule
|
|
|
|
|
|
|
+ * Show the form for editing the specified reward rule
|
|
|
*/
|
|
*/
|
|
|
- public function create()
|
|
|
|
|
|
|
+ public function edit(int $id): View
|
|
|
{
|
|
{
|
|
|
- $transactionTypes = [
|
|
|
|
|
- 1 => 'Order',
|
|
|
|
|
- 2 => 'Registration',
|
|
|
|
|
- 3 => 'Product Review',
|
|
|
|
|
- 4 => 'Daily Sign In',
|
|
|
|
|
- 5 => 'Referral',
|
|
|
|
|
- 6 => 'Birthday',
|
|
|
|
|
- 7 => 'Share' // 添加分享类型的交易
|
|
|
|
|
- ];
|
|
|
|
|
|
|
+ $rule = RewardActiveRule::findOrFail($id);
|
|
|
|
|
|
|
|
- $storeViews = $this->getStoreViews();
|
|
|
|
|
- $customerGroups = $this->getCustomerGroups();
|
|
|
|
|
|
|
+ // 处理 Store Views 数据
|
|
|
|
|
+ $selectedStoreViews = $this->parseStoreViews($rule);
|
|
|
|
|
+
|
|
|
|
|
+ // 如果规则适用于所有店铺(store_view = '0'),则转换为 'all' 选项
|
|
|
|
|
+ $selectedStoreViewsForSelect = [];
|
|
|
|
|
+ if ($rule->store_view === '0' || empty($selectedStoreViews)) {
|
|
|
|
|
+ $selectedStoreViewsForSelect = ['all'];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $selectedStoreViewsForSelect = $selectedStoreViews;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 处理客户群组数据
|
|
|
|
|
+ $selectedCustomerGroupsArray = $this->parseCustomerGroups($rule);
|
|
|
|
|
+ $selectedCustomerGroupsPoints = $rule->enable_different_points_by_group
|
|
|
|
|
+ ? (json_decode($rule->customer_group_ids, true) ?: [])
|
|
|
|
|
+ : [];
|
|
|
|
|
|
|
|
- // 确保 _config 存在且包含必要的键
|
|
|
|
|
- $view = isset($this->_config['view']) ? $this->_config['view'] : 'rewardpoints::admin.rules.create';
|
|
|
|
|
|
|
+ $view = $this->_config['view'] ?? 'rewardpoints::admin.rules.edit';
|
|
|
|
|
|
|
|
- return view($view, compact('transactionTypes', 'storeViews', 'customerGroups'));
|
|
|
|
|
|
|
+ return view($view, [
|
|
|
|
|
+ 'rule' => $rule,
|
|
|
|
|
+ 'transactionTypes' => self::TRANSACTION_TYPES,
|
|
|
|
|
+ 'storeViews' => $this->getStoreViews(),
|
|
|
|
|
+ 'customerGroups' => $this->getCustomerGroups(),
|
|
|
|
|
+ 'selectedStoreViewsForSelect' => $selectedStoreViewsForSelect,
|
|
|
|
|
+ 'selectedCustomerGroupsArray' => $selectedCustomerGroupsArray,
|
|
|
|
|
+ 'selectedCustomerGroupsPoints' => $selectedCustomerGroupsPoints,
|
|
|
|
|
+ 'colorClasses' => self::COLOR_CLASSES,
|
|
|
|
|
+ ]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Store a newly created reward rule
|
|
* Store a newly created reward rule
|
|
|
*/
|
|
*/
|
|
|
- public function store(Request $request)
|
|
|
|
|
|
|
+ public function store(Request $request): RedirectResponse
|
|
|
{
|
|
{
|
|
|
- $this->validate($request, [
|
|
|
|
|
- 'rule_name' => 'required|string|max:255',
|
|
|
|
|
- 'type_of_transaction' => 'required|integer|in:1,2,3,4,5,6,7',
|
|
|
|
|
- 'status' => 'required|boolean',
|
|
|
|
|
- 'enable_different_points_by_group' => 'nullable|boolean',
|
|
|
|
|
- //'default_expired' => 'nullable|boolean',
|
|
|
|
|
- 'expired_day' => 'nullable|integer|min:0',
|
|
|
|
|
- //'coupon_code' => 'nullable|string|max:255',
|
|
|
|
|
- ]);
|
|
|
|
|
|
|
+ $validated = $this->validateStoreRequest($request);
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
- $data = $request->only([
|
|
|
|
|
- 'rule_name',
|
|
|
|
|
- 'type_of_transaction',
|
|
|
|
|
- 'store_view',
|
|
|
|
|
- //'default_expired',
|
|
|
|
|
- 'expired_day',
|
|
|
|
|
- //'date_event',
|
|
|
|
|
- 'comment',
|
|
|
|
|
- //'coupon_code',
|
|
|
|
|
- 'status',
|
|
|
|
|
- 'enable_different_points_by_group'
|
|
|
|
|
- ]);
|
|
|
|
|
-
|
|
|
|
|
- // 处理 store views
|
|
|
|
|
- if (isset($data['store_view']) && is_array($data['store_view'])) {
|
|
|
|
|
- $data['store_view'] = implode(',', $data['store_view']);
|
|
|
|
|
- } else {
|
|
|
|
|
- $data['store_view'] = '0';
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 根据是否启用不同群组不同积分来处理客户群组和积分
|
|
|
|
|
- if ($request->get('enable_different_points_by_group')) {
|
|
|
|
|
- // 当启用不同群组不同积分时,将群组积分数据存储为JSON
|
|
|
|
|
- $groupPoints = $request->get('group_points', []);
|
|
|
|
|
- $data['customer_group_ids'] = json_encode($groupPoints);
|
|
|
|
|
- // 统一积分为0,因为实际积分存储在customer_group_ids中
|
|
|
|
|
- $data['reward_point'] = 0;
|
|
|
|
|
- } else {
|
|
|
|
|
- // 验证统一积分值
|
|
|
|
|
- $this->validate($request, [
|
|
|
|
|
- 'reward_point' => 'required|integer|min:0',
|
|
|
|
|
- ]);
|
|
|
|
|
- $data['reward_point'] = $request->get('reward_point');
|
|
|
|
|
-
|
|
|
|
|
- // 处理客户群组IDs
|
|
|
|
|
- if (isset($request['customer_group_ids']) && is_array($request['customer_group_ids'])) {
|
|
|
|
|
- $data['customer_group_ids'] = implode(',', $request['customer_group_ids']);
|
|
|
|
|
- } else {
|
|
|
|
|
- $data['customer_group_ids'] = '';
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- $rule = RewardActiveRule::create($data);
|
|
|
|
|
|
|
+ $data = $this->prepareDataForSave($request, $validated);
|
|
|
|
|
+ RewardActiveRule::create($data);
|
|
|
|
|
|
|
|
session()->flash('success', 'Reward rule created successfully.');
|
|
session()->flash('success', 'Reward rule created successfully.');
|
|
|
|
|
|
|
|
- $redirectRoute = isset($this->_config['redirect']) ? $this->_config['redirect'] : 'admin.reward-points.rules.index';
|
|
|
|
|
- return redirect()->route($redirectRoute);
|
|
|
|
|
-
|
|
|
|
|
- } catch (\Exception $e) {
|
|
|
|
|
|
|
+ return $this->redirectToIndex();
|
|
|
|
|
+ } catch (Exception $e) {
|
|
|
session()->flash('error', 'Error creating reward rule: ' . $e->getMessage());
|
|
session()->flash('error', 'Error creating reward rule: ' . $e->getMessage());
|
|
|
return redirect()->back()->withInput();
|
|
return redirect()->back()->withInput();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * Show the form for editing the specified reward rule
|
|
|
|
|
- */
|
|
|
|
|
- public function edit($id)
|
|
|
|
|
- {
|
|
|
|
|
- $rule = RewardActiveRule::findOrFail($id);
|
|
|
|
|
-
|
|
|
|
|
- $transactionTypes = [
|
|
|
|
|
- 1 => 'Order',
|
|
|
|
|
- 2 => 'Registration',
|
|
|
|
|
- 3 => 'Product Review',
|
|
|
|
|
- 4 => 'Daily Sign In',
|
|
|
|
|
- 5 => 'Referral',
|
|
|
|
|
- 6 => 'Birthday',
|
|
|
|
|
- 7 => 'Share' // 添加分享类型的交易
|
|
|
|
|
- ];
|
|
|
|
|
-
|
|
|
|
|
- $storeViews = $this->getStoreViews();
|
|
|
|
|
- $customerGroups = $this->getCustomerGroups();
|
|
|
|
|
-
|
|
|
|
|
- // 解析存储的值
|
|
|
|
|
- $selectedStoreViews = $rule->store_view ? explode(',', $rule->store_view) : [];
|
|
|
|
|
-
|
|
|
|
|
- // 如果启用了不同群组不同积分,则解析customer_group_ids为数组
|
|
|
|
|
- if ($rule->enable_different_points_by_group) {
|
|
|
|
|
- $selectedCustomerGroups = json_decode($rule->customer_group_ids, true) ?: [];
|
|
|
|
|
- } else {
|
|
|
|
|
- $selectedCustomerGroups = $rule->customer_group_ids ? explode(',', $rule->customer_group_ids) : [];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 确保 _config 存在且包含必要的键
|
|
|
|
|
- $view = isset($this->_config['view']) ? $this->_config['view'] : 'rewardpoints::admin.rules.edit';
|
|
|
|
|
-
|
|
|
|
|
- return view($view, compact(
|
|
|
|
|
- 'rule',
|
|
|
|
|
- 'transactionTypes',
|
|
|
|
|
- 'storeViews',
|
|
|
|
|
- 'customerGroups',
|
|
|
|
|
- 'selectedStoreViews',
|
|
|
|
|
- 'selectedCustomerGroups'
|
|
|
|
|
- ));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Update the specified reward rule
|
|
* Update the specified reward rule
|
|
|
*/
|
|
*/
|
|
|
- public function update(Request $request, $id)
|
|
|
|
|
|
|
+ public function update(Request $request, int $id): RedirectResponse
|
|
|
{
|
|
{
|
|
|
- $this->validate($request, [
|
|
|
|
|
- 'rule_name' => 'required|string|max:255',
|
|
|
|
|
- 'type_of_transaction' => 'required|integer|in:1,2,3,4,5,6,7',
|
|
|
|
|
- 'status' => 'required|boolean',
|
|
|
|
|
- 'enable_different_points_by_group' => 'nullable|boolean',
|
|
|
|
|
- 'default_expired' => 'nullable|boolean',
|
|
|
|
|
- 'expired_day' => 'nullable|integer|min:0',
|
|
|
|
|
- 'coupon_code' => 'nullable|string|max:255',
|
|
|
|
|
- ]);
|
|
|
|
|
|
|
+ $validated = $this->validateUpdateRequest($request);
|
|
|
|
|
+ $rule = RewardActiveRule::findOrFail($id);
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
- $rule = RewardActiveRule::findOrFail($id);
|
|
|
|
|
|
|
+ $data = $this->prepareDataForSave($request, $validated);
|
|
|
|
|
+
|
|
|
|
|
+ // 确保 enable_different_points_by_group 字段被正确设置
|
|
|
|
|
+ $data['enable_different_points_by_group'] = $request->boolean('enable_different_points_by_group');
|
|
|
|
|
|
|
|
- $data = $request->only([
|
|
|
|
|
- 'rule_name',
|
|
|
|
|
- 'type_of_transaction',
|
|
|
|
|
- 'store_view',
|
|
|
|
|
- 'default_expired',
|
|
|
|
|
- 'expired_day',
|
|
|
|
|
- 'date_event',
|
|
|
|
|
- 'comment',
|
|
|
|
|
- 'coupon_code',
|
|
|
|
|
- 'status',
|
|
|
|
|
- 'enable_different_points_by_group'
|
|
|
|
|
- ]);
|
|
|
|
|
-
|
|
|
|
|
- // 处理 store views
|
|
|
|
|
- if (isset($data['store_view']) && is_array($data['store_view'])) {
|
|
|
|
|
- $data['store_view'] = implode(',', $data['store_view']);
|
|
|
|
|
- } else {
|
|
|
|
|
- $data['store_view'] = '0';
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 根据是否启用不同群组不同积分来处理客户群组和积分
|
|
|
|
|
- if ($request->get('enable_different_points_by_group')) {
|
|
|
|
|
- // 当启用不同群组不同积分时,将群组积分数据存储为JSON
|
|
|
|
|
- $groupPoints = $request->get('group_points', []);
|
|
|
|
|
- $data['customer_group_ids'] = json_encode($groupPoints);
|
|
|
|
|
- // 统一积分为0,因为实际积分存储在customer_group_ids中
|
|
|
|
|
- $data['reward_point'] = 0;
|
|
|
|
|
- } else {
|
|
|
|
|
- // 验证统一积分值
|
|
|
|
|
- $this->validate($request, [
|
|
|
|
|
- 'reward_point' => 'required|integer|min:0',
|
|
|
|
|
- ]);
|
|
|
|
|
- $data['reward_point'] = $request->get('reward_point');
|
|
|
|
|
-
|
|
|
|
|
- // 处理客户群组IDs
|
|
|
|
|
- if (isset($request['customer_group_ids']) && is_array($request['customer_group_ids'])) {
|
|
|
|
|
- $data['customer_group_ids'] = implode(',', $request['customer_group_ids']);
|
|
|
|
|
- } else {
|
|
|
|
|
- $data['customer_group_ids'] = '';
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
$rule->update($data);
|
|
$rule->update($data);
|
|
|
|
|
|
|
|
session()->flash('success', 'Reward rule updated successfully.');
|
|
session()->flash('success', 'Reward rule updated successfully.');
|
|
|
|
|
|
|
|
- $redirectRoute = isset($this->_config['redirect']) ? $this->_config['redirect'] : 'admin.reward-points.rules.index';
|
|
|
|
|
- return redirect()->route($redirectRoute);
|
|
|
|
|
-
|
|
|
|
|
- } catch (\Exception $e) {
|
|
|
|
|
|
|
+ return $this->redirectToIndex();
|
|
|
|
|
+ } catch (Exception $e) {
|
|
|
session()->flash('error', 'Error updating reward rule: ' . $e->getMessage());
|
|
session()->flash('error', 'Error updating reward rule: ' . $e->getMessage());
|
|
|
return redirect()->back()->withInput();
|
|
return redirect()->back()->withInput();
|
|
|
}
|
|
}
|
|
@@ -263,45 +180,36 @@ class RuleController extends Controller
|
|
|
/**
|
|
/**
|
|
|
* Remove the specified reward rule
|
|
* Remove the specified reward rule
|
|
|
*/
|
|
*/
|
|
|
- public function destroy($id)
|
|
|
|
|
|
|
+ public function destroy(int $id): JsonResponse|RedirectResponse
|
|
|
{
|
|
{
|
|
|
try {
|
|
try {
|
|
|
$rule = RewardActiveRule::findOrFail($id);
|
|
$rule = RewardActiveRule::findOrFail($id);
|
|
|
$rule->delete();
|
|
$rule->delete();
|
|
|
|
|
|
|
|
- session()->flash('success', 'Reward rule deleted successfully.');
|
|
|
|
|
-
|
|
|
|
|
- // 检查请求是否是 AJAX 请求
|
|
|
|
|
|
|
+ $message = 'Reward rule deleted successfully.';
|
|
|
|
|
+ session()->flash('success', $message);
|
|
|
|
|
+
|
|
|
if (request()->ajax()) {
|
|
if (request()->ajax()) {
|
|
|
- return response()->json([
|
|
|
|
|
- 'status' => true,
|
|
|
|
|
- 'message' => 'Reward rule deleted successfully.'
|
|
|
|
|
- ]);
|
|
|
|
|
- } else {
|
|
|
|
|
- // 非 AJAX 请求则进行重定向
|
|
|
|
|
- $redirectRoute = isset($this->_config['redirect']) ? $this->_config['redirect'] : 'admin.reward-points.rules.index';
|
|
|
|
|
- return redirect()->route($redirectRoute);
|
|
|
|
|
|
|
+ return response()->json(['status' => true, 'message' => $message]);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- } catch (\Exception $e) {
|
|
|
|
|
- session()->flash('error', 'Error deleting reward rule: ' . $e->getMessage());
|
|
|
|
|
-
|
|
|
|
|
|
|
+ return $this->redirectToIndex();
|
|
|
|
|
+ } catch (Exception $e) {
|
|
|
|
|
+ $message = 'Error deleting reward rule: ' . $e->getMessage();
|
|
|
|
|
+ session()->flash('error', $message);
|
|
|
|
|
+
|
|
|
if (request()->ajax()) {
|
|
if (request()->ajax()) {
|
|
|
- return response()->json([
|
|
|
|
|
- 'status' => false,
|
|
|
|
|
- 'message' => 'Error deleting reward rule.'
|
|
|
|
|
- ]);
|
|
|
|
|
- } else {
|
|
|
|
|
- $redirectRoute = isset($this->_config['redirect']) ? $this->_config['redirect'] : 'admin.reward-points.rules.index';
|
|
|
|
|
- return redirect()->route($redirectRoute)->with('error', 'Error deleting reward rule: ' . $e->getMessage());
|
|
|
|
|
|
|
+ return response()->json(['status' => false, 'message' => 'Error deleting reward rule.'], 500);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ return $this->redirectToIndex()->with('error', $message);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Update rule status
|
|
* Update rule status
|
|
|
*/
|
|
*/
|
|
|
- public function updateStatus($id, Request $request)
|
|
|
|
|
|
|
+ public function updateStatus(int $id, Request $request): JsonResponse
|
|
|
{
|
|
{
|
|
|
try {
|
|
try {
|
|
|
$rule = RewardActiveRule::findOrFail($id);
|
|
$rule = RewardActiveRule::findOrFail($id);
|
|
@@ -310,25 +218,219 @@ class RuleController extends Controller
|
|
|
|
|
|
|
|
return response()->json([
|
|
return response()->json([
|
|
|
'status' => true,
|
|
'status' => true,
|
|
|
- 'message' => 'Rule status updated successfully.'
|
|
|
|
|
|
|
+ 'message' => 'Rule status updated successfully.',
|
|
|
]);
|
|
]);
|
|
|
-
|
|
|
|
|
- } catch (\Exception $e) {
|
|
|
|
|
|
|
+ } catch (Exception $e) {
|
|
|
return response()->json([
|
|
return response()->json([
|
|
|
'status' => false,
|
|
'status' => false,
|
|
|
- 'message' => 'Error updating rule status.'
|
|
|
|
|
|
|
+ 'message' => 'Error updating rule status.',
|
|
|
|
|
+ ], 500);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Validate store request
|
|
|
|
|
+ */
|
|
|
|
|
+ private function validateStoreRequest(Request $request): array
|
|
|
|
|
+ {
|
|
|
|
|
+ $rules = [
|
|
|
|
|
+ 'rule_name' => 'required|string|max:255',
|
|
|
|
|
+ 'type_of_transaction' => ['required', 'integer', Rule::in(self::VALID_TRANSACTION_TYPES)],
|
|
|
|
|
+ 'status' => 'required|boolean',
|
|
|
|
|
+ 'enable_different_points_by_group' => 'nullable|boolean',
|
|
|
|
|
+ 'expired_day' => 'nullable|integer|min:0',
|
|
|
|
|
+ 'comment' => 'nullable|string|max:500',
|
|
|
|
|
+ 'store_view' => 'nullable|array',
|
|
|
|
|
+ 'store_view.*' => 'nullable|string',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ return $request->validate($rules);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Validate update request
|
|
|
|
|
+ */
|
|
|
|
|
+ private function validateUpdateRequest(Request $request): array
|
|
|
|
|
+ {
|
|
|
|
|
+ $rules = [
|
|
|
|
|
+ 'rule_name' => 'required|string|max:255',
|
|
|
|
|
+ 'type_of_transaction' => ['required', 'integer', Rule::in(self::VALID_TRANSACTION_TYPES)],
|
|
|
|
|
+ 'status' => 'required|boolean',
|
|
|
|
|
+ 'enable_different_points_by_group' => 'nullable|boolean',
|
|
|
|
|
+ 'default_expired' => 'nullable|boolean',
|
|
|
|
|
+ 'expired_day' => 'nullable|integer|min:0',
|
|
|
|
|
+ 'coupon_code' => 'nullable|string|max:255',
|
|
|
|
|
+ 'comment' => 'nullable|string|max:500',
|
|
|
|
|
+ 'store_view' => 'nullable|array',
|
|
|
|
|
+ 'store_view.*' => 'nullable|string',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ return $request->validate($rules);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Prepare data for saving
|
|
|
|
|
+ */
|
|
|
|
|
+ private function prepareDataForSave(Request $request, array $validated): array
|
|
|
|
|
+ {
|
|
|
|
|
+ $data = array_intersect_key($validated, array_flip([
|
|
|
|
|
+ 'rule_name',
|
|
|
|
|
+ 'type_of_transaction',
|
|
|
|
|
+ 'default_expired',
|
|
|
|
|
+ 'expired_day',
|
|
|
|
|
+ 'date_event',
|
|
|
|
|
+ 'comment',
|
|
|
|
|
+ 'coupon_code',
|
|
|
|
|
+ 'status',
|
|
|
|
|
+ 'enable_different_points_by_group',
|
|
|
|
|
+ ]));
|
|
|
|
|
+
|
|
|
|
|
+ // Handle store views - 修复:确保正确处理 store_view
|
|
|
|
|
+ $storeViews = $request->get('store_view', []);
|
|
|
|
|
+ $data['store_view'] = $this->formatStoreViews($storeViews);
|
|
|
|
|
+
|
|
|
|
|
+ // Handle points configuration
|
|
|
|
|
+ $this->handlePointsConfiguration($request, $data);
|
|
|
|
|
+
|
|
|
|
|
+ return $data;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Format store views for database storage
|
|
|
|
|
+ */
|
|
|
|
|
+ private function formatStoreViews($storeViews): string
|
|
|
|
|
+{
|
|
|
|
|
+ // 如果 storeViews 为空或为 '0',返回 '0' 表示所有店铺
|
|
|
|
|
+ if (empty($storeViews) || $storeViews === '0') {
|
|
|
|
|
+ return '0';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果是单个值,直接返回
|
|
|
|
|
+ if (is_scalar($storeViews) && !empty($storeViews)) {
|
|
|
|
|
+ return (string)$storeViews;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return '0';
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Handle points configuration based on group settings
|
|
|
|
|
+ */
|
|
|
|
|
+ private function handlePointsConfiguration(Request $request, array &$data): void
|
|
|
|
|
+ {
|
|
|
|
|
+ if ($request->boolean('enable_different_points_by_group')) {
|
|
|
|
|
+ $groupPoints = $request->get('group_points', []);
|
|
|
|
|
+
|
|
|
|
|
+ // 确保 $groupPoints 是数组
|
|
|
|
|
+ if (!is_array($groupPoints)) {
|
|
|
|
|
+ $groupPoints = [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 过滤并处理群组积分数据,确保键是字符串或整数
|
|
|
|
|
+ $filteredPoints = [];
|
|
|
|
|
+ foreach ($groupPoints as $groupId => $points) {
|
|
|
|
|
+ // 确保键是标量类型且不为空
|
|
|
|
|
+ if (is_scalar($groupId) && !empty($groupId)) {
|
|
|
|
|
+ // 确保积分值是数字
|
|
|
|
|
+ $pointsValue = is_numeric($points) ? (int)$points : 0;
|
|
|
|
|
+ if ($pointsValue >= 0) {
|
|
|
|
|
+ $filteredPoints[(string)$groupId] = $pointsValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $data['customer_group_ids'] = !empty($filteredPoints) ? json_encode($filteredPoints) : '{}';
|
|
|
|
|
+ $data['reward_point'] = 0;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $request->validate([
|
|
|
|
|
+ 'reward_point' => 'required|integer|min:0',
|
|
|
]);
|
|
]);
|
|
|
|
|
+ $data['reward_point'] = (int)$request->get('reward_point');
|
|
|
|
|
+ $data['customer_group_ids'] = $this->formatCustomerGroups($request->get('customer_group_ids', []));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Format customer groups for database storage
|
|
|
|
|
+ */
|
|
|
|
|
+ private function formatCustomerGroups($customerGroups): string
|
|
|
|
|
+ {
|
|
|
|
|
+ if (is_array($customerGroups) && !empty($customerGroups)) {
|
|
|
|
|
+ // 过滤掉空值并确保所有值都是标量
|
|
|
|
|
+ $filtered = [];
|
|
|
|
|
+ foreach ($customerGroups as $groupId) {
|
|
|
|
|
+ if (is_scalar($groupId) && !empty($groupId)) {
|
|
|
|
|
+ $filtered[] = (string)$groupId;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return !empty($filtered) ? implode(',', array_unique($filtered)) : '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Parse store views from rule
|
|
|
|
|
+ */
|
|
|
|
|
+ private function parseStoreViews(RewardActiveRule $rule): array
|
|
|
|
|
+ {
|
|
|
|
|
+ if ($rule->store_view && $rule->store_view !== '0') {
|
|
|
|
|
+ $views = explode(',', $rule->store_view);
|
|
|
|
|
+ // 过滤空值
|
|
|
|
|
+ return array_filter($views, function($view) {
|
|
|
|
|
+ return !empty($view);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Parse customer groups from rule
|
|
|
|
|
+ */
|
|
|
|
|
+ private function parseCustomerGroups(RewardActiveRule $rule): array
|
|
|
|
|
+ {
|
|
|
|
|
+ if ($rule->enable_different_points_by_group) {
|
|
|
|
|
+ $decoded = json_decode($rule->customer_group_ids, true);
|
|
|
|
|
+ if (is_array($decoded)) {
|
|
|
|
|
+ // 确保解码后的数据格式正确
|
|
|
|
|
+ $result = [];
|
|
|
|
|
+ foreach ($decoded as $groupId => $points) {
|
|
|
|
|
+ if (is_scalar($groupId) && !empty($groupId)) {
|
|
|
|
|
+ $result[(string)$groupId] = is_numeric($points) ? (int)$points : 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return $result;
|
|
|
|
|
+ }
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($rule->customer_group_ids && $rule->customer_group_ids !== '') {
|
|
|
|
|
+ $groups = explode(',', $rule->customer_group_ids);
|
|
|
|
|
+ // 过滤空值
|
|
|
|
|
+ return array_filter($groups, function($group) {
|
|
|
|
|
+ return !empty($group);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* Get all store views
|
|
* Get all store views
|
|
|
*/
|
|
*/
|
|
|
- protected function getStoreViews()
|
|
|
|
|
|
|
+ protected function getStoreViews(): array
|
|
|
{
|
|
{
|
|
|
try {
|
|
try {
|
|
|
- return \Webkul\Core\Models\Channel::pluck('name', 'code')->toArray();
|
|
|
|
|
- } catch (\Exception $e) {
|
|
|
|
|
|
|
+ $channels = Channel::all();
|
|
|
|
|
+ $storeViews = [];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($channels as $channel) {
|
|
|
|
|
+ $storeViews[$channel->code] = $channel->name;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $storeViews;
|
|
|
|
|
+ } catch (Exception $e) {
|
|
|
return ['0' => 'All Stores'];
|
|
return ['0' => 'All Stores'];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -336,12 +438,53 @@ class RuleController extends Controller
|
|
|
/**
|
|
/**
|
|
|
* Get all customer groups
|
|
* Get all customer groups
|
|
|
*/
|
|
*/
|
|
|
- protected function getCustomerGroups()
|
|
|
|
|
|
|
+ protected function getCustomerGroups(): array
|
|
|
{
|
|
{
|
|
|
try {
|
|
try {
|
|
|
- return \Webkul\Customer\Models\CustomerGroup::pluck('name', 'id')->toArray();
|
|
|
|
|
- } catch (\Exception $e) {
|
|
|
|
|
|
|
+ $groups = CustomerGroup::orderBy('id')->get();
|
|
|
|
|
+ $customerGroups = [];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($groups as $group) {
|
|
|
|
|
+ $customerGroups[$group->id] = $group->name;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $customerGroups;
|
|
|
|
|
+ } catch (Exception $e) {
|
|
|
return ['0' => 'All Groups'];
|
|
return ['0' => 'All Groups'];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Get transaction type configuration
|
|
|
|
|
+ */
|
|
|
|
|
+ public function getTransactionTypeConfig(): array
|
|
|
|
|
+ {
|
|
|
|
|
+ return self::TRANSACTION_TYPES;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Get transaction type name
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function getTransactionTypeName(int $typeId): string
|
|
|
|
|
+ {
|
|
|
|
|
+ return self::TRANSACTION_TYPES[$typeId]['name'] ?? 'Unknown';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Get transaction type color classes
|
|
|
|
|
+ */
|
|
|
|
|
+ protected function getTransactionTypeColorClass(int $typeId): string
|
|
|
|
|
+ {
|
|
|
|
|
+ $color = self::TRANSACTION_TYPES[$typeId]['color'] ?? 'gray';
|
|
|
|
|
+ return self::COLOR_CLASSES[$color] ?? self::COLOR_CLASSES['gray'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Redirect to index route
|
|
|
|
|
+ */
|
|
|
|
|
+ private function redirectToIndex(): RedirectResponse
|
|
|
|
|
+ {
|
|
|
|
|
+ $route = $this->_config['redirect'] ?? 'admin.reward-points.rules.index';
|
|
|
|
|
+ return redirect()->route($route);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|