数据库: - positions 新增 daily_reward_limit(单日累计上限) - positions 新增 recipient_daily_limit(同一接收者每日次数上限) 后端: - CurrencySource::POSITION_REWARD 新枚举值 - AdminCommandController::reward() 三层限额校验 ① 单次上限 ② 单日累计上限 ③ 同一接收者每日次数 写履职记录(PositionAuthorityLog)+ UserCurrencyService 聊天室悄悄话通知接收者 - POST /command/reward 路由注册 前端(user-actions.blade.php): - 名片按钮行 2+1 布局(加好友/送礼物/送金币) - 送金币仅在 myMaxReward>0 时显示(职务持有者) - 内联奖励金币面板:金额输入 + 确认发放 + 说明文字 - sendReward() 前端校验 + API 调用 + chatDialog 反馈 后台(positions/index): - 编辑表单新增两个奖励限额字段 - PositionController 验证规则同步更新
115 lines
4.0 KiB
PHP
115 lines
4.0 KiB
PHP
<?php
|
||
|
||
/**
|
||
* 文件功能:后台职务管理控制器
|
||
* 提供职务的 CRUD 功能,包含任命权限白名单(多选 position_appoint_limits)的同步
|
||
* 职务属于部门,包含等级、图标、人数上限、奖励上限等配置
|
||
*
|
||
* @author ChatRoom Laravel
|
||
*
|
||
* @version 1.0.0
|
||
*/
|
||
|
||
namespace App\Http\Controllers\Admin;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Models\Department;
|
||
use App\Models\Position;
|
||
use Illuminate\Http\RedirectResponse;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\View\View;
|
||
|
||
class PositionController extends Controller
|
||
{
|
||
/**
|
||
* 职务列表页
|
||
*/
|
||
public function index(): View
|
||
{
|
||
// 按部门分组展示
|
||
$departments = Department::with([
|
||
'positions' => fn ($q) => $q->withCount(['activeUserPositions'])->ordered(),
|
||
])->ordered()->get();
|
||
|
||
// 全部职务(供任命白名单多选框使用)
|
||
$allPositions = Position::with('department')->orderByDesc('rank')->get();
|
||
|
||
return view('admin.positions.index', compact('departments', 'allPositions'));
|
||
}
|
||
|
||
/**
|
||
* 创建职务(同时同步任命白名单)
|
||
*/
|
||
public function store(Request $request): RedirectResponse
|
||
{
|
||
$data = $request->validate([
|
||
'department_id' => 'required|exists:departments,id',
|
||
'name' => 'required|string|max:50',
|
||
'icon' => 'nullable|string|max:10',
|
||
'rank' => 'required|integer|min:0|max:99',
|
||
'level' => 'required|integer|min:1|max:100',
|
||
'max_persons' => 'nullable|integer|min:1',
|
||
'max_reward' => 'nullable|integer|min:0',
|
||
'daily_reward_limit' => 'nullable|integer|min:0',
|
||
'recipient_daily_limit' => 'nullable|integer|min:0',
|
||
'sort_order' => 'required|integer|min:0',
|
||
'appointable_ids' => 'nullable|array',
|
||
'appointable_ids.*' => 'exists:positions,id',
|
||
]);
|
||
|
||
$appointableIds = $data['appointable_ids'] ?? [];
|
||
unset($data['appointable_ids']);
|
||
|
||
$position = Position::create($data);
|
||
|
||
// 同步任命白名单(有选则写,没选则清空=无任命权)
|
||
$position->appointablePositions()->sync($appointableIds);
|
||
|
||
return redirect()->route('admin.positions.index')->with('success', "职务【{$data['name']}】创建成功!");
|
||
}
|
||
|
||
/**
|
||
* 更新职务(含任命白名单同步)
|
||
*/
|
||
public function update(Request $request, Position $position): RedirectResponse
|
||
{
|
||
$data = $request->validate([
|
||
'department_id' => 'required|exists:departments,id',
|
||
'name' => 'required|string|max:50',
|
||
'icon' => 'nullable|string|max:10',
|
||
'rank' => 'required|integer|min:0|max:99',
|
||
'level' => 'required|integer|min:1|max:100',
|
||
'max_persons' => 'nullable|integer|min:1',
|
||
'max_reward' => 'nullable|integer|min:0',
|
||
'daily_reward_limit' => 'nullable|integer|min:0',
|
||
'recipient_daily_limit' => 'nullable|integer|min:0',
|
||
'sort_order' => 'required|integer|min:0',
|
||
'appointable_ids' => 'nullable|array',
|
||
'appointable_ids.*' => 'exists:positions,id',
|
||
]);
|
||
|
||
$appointableIds = $data['appointable_ids'] ?? [];
|
||
unset($data['appointable_ids']);
|
||
|
||
$position->update($data);
|
||
$position->appointablePositions()->sync($appointableIds);
|
||
|
||
return redirect()->route('admin.positions.index')->with('success', "职务【{$data['name']}】更新成功!");
|
||
}
|
||
|
||
/**
|
||
* 删除职务(有在职人员时拒绝)
|
||
*/
|
||
public function destroy(Position $position): RedirectResponse
|
||
{
|
||
if ($position->isFull() || $position->activeUserPositions()->exists()) {
|
||
return redirect()->route('admin.positions.index')
|
||
->with('error', "职务【{$position->name}】尚有在职人员,请先撤销后再删除。");
|
||
}
|
||
|
||
$position->delete();
|
||
|
||
return redirect()->route('admin.positions.index')->with('success', "职务【{$position->name}】已删除!");
|
||
}
|
||
}
|