feat: 增加待办提醒筛选和默认开始日期
This commit is contained in:
parent
4519a0e627
commit
2396c4bfbc
@ -19,6 +19,13 @@ use Throwable;
|
||||
class SystemizationTodos extends Controller
|
||||
{
|
||||
private const OVERDUE_FILTER = '__overdue__';
|
||||
private const REMINDER_OPTIONS = [
|
||||
'overdue' => '已逾期',
|
||||
'today' => '今天到期',
|
||||
'upcoming' => '剩余天数',
|
||||
'pending' => '时间待定',
|
||||
'none' => '无提醒',
|
||||
];
|
||||
|
||||
public function page(): array
|
||||
{
|
||||
@ -36,6 +43,24 @@ class SystemizationTodos extends Controller
|
||||
} elseif ($filters['status'] === SystemizationTodo::STATUS_COMPLETED) {
|
||||
$query->where('status', $filters['status']);
|
||||
}
|
||||
if ($filters['reminder'] !== '') {
|
||||
if ($filters['reminder'] === 'overdue') {
|
||||
$query->where('status', '<>', SystemizationTodo::STATUS_COMPLETED)
|
||||
->whereNotNull('due_date')
|
||||
->whereDate('due_date', '<', today());
|
||||
} elseif ($filters['reminder'] === 'today') {
|
||||
$query->where('status', '<>', SystemizationTodo::STATUS_COMPLETED)
|
||||
->whereDate('due_date', today());
|
||||
} elseif ($filters['reminder'] === 'upcoming') {
|
||||
$query->where('status', '<>', SystemizationTodo::STATUS_COMPLETED)
|
||||
->whereDate('due_date', '>', today());
|
||||
} elseif ($filters['reminder'] === 'pending') {
|
||||
$query->where('status', '<>', SystemizationTodo::STATUS_COMPLETED)
|
||||
->whereNull('due_date');
|
||||
} elseif ($filters['reminder'] === 'none') {
|
||||
$query->where('status', SystemizationTodo::STATUS_COMPLETED);
|
||||
}
|
||||
}
|
||||
if ($filters['category'] !== '') {
|
||||
$query->where('category', $filters['category']);
|
||||
}
|
||||
@ -150,6 +175,12 @@ class SystemizationTodos extends Controller
|
||||
'todoAssignees' => $this->peopleOptions('assignee'),
|
||||
'todoStatuses' => SystemizationTodo::STATUSES,
|
||||
'todoStatusOptions' => $statusOptions,
|
||||
'todoReminderOptions' => collect(self::REMINDER_OPTIONS)
|
||||
->map(static fn (string $label, string $value): array => [
|
||||
'value' => $value,
|
||||
'label' => $label,
|
||||
])
|
||||
->values(),
|
||||
'todoReturnFilters' => base64_encode(json_encode(
|
||||
$filters,
|
||||
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
|
||||
@ -602,6 +633,7 @@ class SystemizationTodos extends Controller
|
||||
{
|
||||
return [
|
||||
'status' => $this->normalizeStatusValue(request('status')),
|
||||
'reminder' => $this->normalizeReminderValue(request('reminder')),
|
||||
'category' => trim((string) request('category', '')),
|
||||
'owners' => $this->peopleFilter('owner'),
|
||||
'assignees' => $this->peopleFilter('assignee'),
|
||||
@ -624,6 +656,13 @@ class SystemizationTodos extends Controller
|
||||
: '';
|
||||
}
|
||||
|
||||
private function normalizeReminderValue(mixed $value): string
|
||||
{
|
||||
$reminder = trim((string) $value);
|
||||
|
||||
return array_key_exists($reminder, self::REMINDER_OPTIONS) ? $reminder : '';
|
||||
}
|
||||
|
||||
private function peopleFilter(string $key): array
|
||||
{
|
||||
return collect((array) request($key, []))
|
||||
@ -818,6 +857,7 @@ class SystemizationTodos extends Controller
|
||||
|
||||
return array_filter([
|
||||
'status' => $this->normalizeStatusValue($filters['status'] ?? null),
|
||||
'reminder' => $this->normalizeReminderValue($filters['reminder'] ?? null),
|
||||
'category' => $category,
|
||||
'owner' => $owners,
|
||||
'assignee' => $assignees,
|
||||
|
||||
@ -264,6 +264,12 @@
|
||||
<option value="{{ $category }}" @selected($todoFilters['category'] === $category)>{{ $category }}</option>
|
||||
@endforeach
|
||||
</select></label>
|
||||
<label>提醒<select name="reminder">
|
||||
<option value="">全部提醒</option>
|
||||
@foreach ($todoReminderOptions as $reminderOption)
|
||||
<option value="{{ $reminderOption['value'] }}" @selected($todoFilters['reminder'] === $reminderOption['value'])>{{ $reminderOption['label'] }}</option>
|
||||
@endforeach
|
||||
</select></label>
|
||||
@php
|
||||
$selectedOwners = $todoOwners->filter(
|
||||
static fn (string $owner): bool => in_array($owner, $todoFilters['owners'], true)
|
||||
@ -595,7 +601,7 @@
|
||||
<div class="sys-todo-scrollrail__spacer" data-sys-todo-scrollrail-spacer></div>
|
||||
</div>
|
||||
|
||||
<dialog class="sys-todo-dialog" id="sysTodoDialog" aria-labelledby="sysTodoDialogTitle">
|
||||
<dialog class="sys-todo-dialog" id="sysTodoDialog" aria-labelledby="sysTodoDialogTitle" data-sys-todo-default-start-date="{{ today()->toDateString() }}">
|
||||
<form method="POST" enctype="multipart/form-data" data-sys-todo-form>
|
||||
@csrf
|
||||
<input type="hidden" name="_method" value="POST" data-sys-todo-method>
|
||||
@ -783,6 +789,7 @@
|
||||
var dialog = document.getElementById('sysTodoDialog');
|
||||
var form = dialog.querySelector('[data-sys-todo-form]');
|
||||
var pageRoot = dialog.closest('.sys-todo-page');
|
||||
var defaultStartDate = dialog.getAttribute('data-sys-todo-default-start-date') || '';
|
||||
if (window.CaiWuDatePicker) window.CaiWuDatePicker.setup(pageRoot || document);
|
||||
var methodInput = dialog.querySelector('[data-sys-todo-method]');
|
||||
var title = document.getElementById('sysTodoDialogTitle');
|
||||
@ -1382,7 +1389,7 @@
|
||||
setCategoryValue('');
|
||||
refreshSectionOptions('');
|
||||
setOwnerValue('');
|
||||
applyDateControl(startDateControl, '', '');
|
||||
applyDateControl(startDateControl, defaultStartDate, '');
|
||||
applyDateControl(dueDateControl, '', '');
|
||||
}
|
||||
if (!currentTodoId && !(payload && payload.status)) {
|
||||
|
||||
@ -34,8 +34,11 @@ class SystemizationTodosTest extends FeatureTestCase
|
||||
->assertSeeText('开始时间')
|
||||
->assertSeeText('完成时间')
|
||||
->assertSeeText('待定')
|
||||
->assertSee('name="reminder"', false)
|
||||
->assertSeeText('全部提醒')
|
||||
->assertSeeText('完成情况 / 备注')
|
||||
->assertSeeText('提醒')
|
||||
->assertSee('data-sys-todo-default-start-date', false)
|
||||
->assertSee('data-sys-todo-inline-add', false)
|
||||
->assertSee('data-sys-todo-col-resizer', false)
|
||||
->assertSee('data-sys-todo-reset-columns', false)
|
||||
@ -478,6 +481,7 @@ class SystemizationTodosTest extends FeatureTestCase
|
||||
$todo = $this->createTodo('收入', '平台收入核对', '筛选保持测试', '2026-10-30', 1);
|
||||
$returnFilters = base64_encode(json_encode([
|
||||
'status' => SystemizationTodo::STATUS_INCOMPLETE,
|
||||
'reminder' => 'upcoming',
|
||||
'category' => '收入',
|
||||
'owners' => ['晨曦', '人参'],
|
||||
'assignees' => ['栎阳'],
|
||||
@ -501,6 +505,7 @@ class SystemizationTodosTest extends FeatureTestCase
|
||||
$location = (string) $response->headers->get('Location');
|
||||
parse_str((string) parse_url($location, PHP_URL_QUERY), $query);
|
||||
$this->assertSame(SystemizationTodo::STATUS_INCOMPLETE, $query['status'] ?? null);
|
||||
$this->assertSame('upcoming', $query['reminder'] ?? null);
|
||||
$this->assertSame('收入', $query['category'] ?? null);
|
||||
$this->assertSame(['晨曦', '人参'], $query['owner'] ?? null);
|
||||
$this->assertSame(['栎阳'], $query['assignee'] ?? null);
|
||||
@ -526,11 +531,16 @@ class SystemizationTodosTest extends FeatureTestCase
|
||||
]);
|
||||
$legacy = $this->createTodo('收入', '提醒测试', '历史进行中事项', '2026-11-01', 5);
|
||||
$legacy->update(['status' => '进行中']);
|
||||
$pendingDate = $this->createTodo('收入', '提醒测试', '时间待定事项', '2026-10-30', 6);
|
||||
$pendingDate->update(['due_date' => null, 'due_note' => '待定']);
|
||||
|
||||
$content = $this->get(route('business.pages.show', [
|
||||
$pageResponse = $this->get(route('business.pages.show', [
|
||||
'section' => 'other',
|
||||
'page' => 'systemization-todos',
|
||||
]))->assertOk()->viewData('content');
|
||||
]))->assertOk()
|
||||
->assertSee('data-sys-todo-default-start-date="2026-10-26"', false)
|
||||
->assertSee("applyDateControl(startDateControl, defaultStartDate, '');", false);
|
||||
$content = $pageResponse->viewData('content');
|
||||
$items = $content['items']->keyBy('title');
|
||||
|
||||
$this->assertSame('逾期 6 天', $items['逾期事项']->reminder_label);
|
||||
@ -538,6 +548,7 @@ class SystemizationTodosTest extends FeatureTestCase
|
||||
$this->assertSame('今天到期', $items['今天到期事项']->reminder_label);
|
||||
$this->assertSame('剩余 4 天', $items['未来事项']->reminder_label);
|
||||
$this->assertSame('—', $items['已完成事项']->reminder_label);
|
||||
$this->assertSame('时间待定', $items['时间待定事项']->reminder_label);
|
||||
$this->assertSame('', $items['已完成事项']->displayProgress());
|
||||
$this->assertSame(SystemizationTodo::STATUS_INCOMPLETE, $items['历史进行中事项']->status_label);
|
||||
|
||||
@ -555,6 +566,23 @@ class SystemizationTodosTest extends FeatureTestCase
|
||||
'status' => SystemizationTodo::STATUS_COMPLETED,
|
||||
]))->assertOk()->viewData('content')['items']->pluck('title');
|
||||
$this->assertSame(['已完成事项'], $completedTitles->all());
|
||||
|
||||
foreach ([
|
||||
'overdue' => ['逾期事项'],
|
||||
'today' => ['今天到期事项'],
|
||||
'upcoming' => ['未来事项', '历史进行中事项'],
|
||||
'pending' => ['时间待定事项'],
|
||||
'none' => ['已完成事项'],
|
||||
] as $reminder => $expectedTitles) {
|
||||
$reminderContent = $this->get(route('business.pages.show', [
|
||||
'section' => 'other',
|
||||
'page' => 'systemization-todos',
|
||||
'reminder' => $reminder,
|
||||
]))->assertOk()->viewData('content');
|
||||
|
||||
$this->assertSame($reminder, $reminderContent['todoFilters']['reminder']);
|
||||
$this->assertSame($expectedTitles, $reminderContent['items']->pluck('title')->all());
|
||||
}
|
||||
} finally {
|
||||
Carbon::setTestNow();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user