feat(财务台账): 优化手工明细日期与账户选择 #455
@ -271,6 +271,13 @@
|
||||
.ledger-manual-input { width:100%; min-width:0; height:1.85rem; padding:0 .42rem; border:1px solid var(--vip-border, #D8D2C7); border-radius:.35rem; background:#fff; color:var(--vip-content-ink, #171717); font:inherit; font-size:.7rem; }
|
||||
.ledger-manual-input:focus { border-color:var(--vip-content-accent-dark, #856632); outline:none; box-shadow:0 0 0 3px rgba(133,102,50,.14); }
|
||||
.ledger-manual-input:disabled { background:#f5f2eb; color:var(--vip-content-muted, #595959); }
|
||||
.ledger-manual-date { display:flex; align-items:stretch; min-width:0; }
|
||||
.ledger-manual-date .ledger-manual-input { flex:1 1 auto; width:auto; min-width:0; border-radius:.35rem 0 0 .35rem; cursor:pointer; }
|
||||
.ledger-manual-date .ledger-manual-input:focus { position:relative; z-index:1; }
|
||||
.ledger-manual-date__button { display:inline-grid; flex:none; place-items:center; width:1.85rem; height:1.85rem; padding:0; border:1px solid var(--vip-content-accent-dark, #856632); border-left:0; border-radius:0 .35rem .35rem 0; background:var(--vip-content-accent-soft, #F7F0DE); color:var(--vip-content-accent-dark, #856632); cursor:pointer; }
|
||||
.ledger-manual-date__button:hover { background:#efe4c8; }
|
||||
.ledger-manual-date__button:focus-visible { position:relative; z-index:2; outline:none; box-shadow:0 0 0 3px rgba(133,102,50,.18); }
|
||||
.ledger-manual-date__button .material-icons-outlined { font-size:1rem; }
|
||||
.ledger-manual-actions { display:flex; align-items:center; gap:.25rem; }
|
||||
.ledger-manual-action { display:inline-grid; place-items:center; width:1.75rem; height:1.75rem; padding:0; border:1px solid var(--vip-border, #D8D2C7); border-radius:.35rem; background:#fff; color:var(--vip-content-muted, #595959); cursor:pointer; }
|
||||
.ledger-manual-action.is-save { border-color:var(--vip-content-accent-dark, #856632); background:var(--vip-content-accent-dark, #856632); color:#fff; }
|
||||
@ -613,15 +620,20 @@
|
||||
@csrf
|
||||
<input type="hidden" name="idempotency_key" value="{{ (string) \Illuminate\Support\Str::uuid() }}" data-ledger-manual-token>
|
||||
</form>
|
||||
<input class="ledger-manual-input" form="ledger-manual-transaction-form" type="date" name="txn_date" value="{{ now()->format('Y-m-d') }}" min="{{ $ledgerOpeningDate }}" required>
|
||||
<div class="ledger-manual-date">
|
||||
<input id="ledger-manual-date" class="ledger-manual-input" form="ledger-manual-transaction-form" type="date" name="txn_date" value="{{ now()->format('Y-m-d') }}" min="{{ $ledgerOpeningDate }}" required data-ledger-manual-date>
|
||||
<button class="ledger-manual-date__button" type="button" aria-label="选择手工明细日期" title="选择日期" data-ledger-manual-date-picker>
|
||||
<span class="material-icons-outlined" aria-hidden="true">calendar_today</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<select class="ledger-manual-input" form="ledger-manual-transaction-form" name="account_short" required>
|
||||
<option value="">选择账户简称</option>
|
||||
<input id="ledger-manual-account" class="ledger-manual-input" form="ledger-manual-transaction-form" type="text" name="account_short" list="ledger-manual-account-options" maxlength="100" placeholder="输入账户简称" autocomplete="off" required data-ledger-manual-account>
|
||||
<datalist id="ledger-manual-account-options">
|
||||
@foreach ($manualTransactionAccountOptions as $option)
|
||||
<option value="{{ $option['value'] }}">{{ $option['label'] }}</option>
|
||||
<option value="{{ $option['value'] }}" label="{{ $option['label'] }}"></option>
|
||||
@endforeach
|
||||
</select>
|
||||
</datalist>
|
||||
</td>
|
||||
<td><input class="ledger-manual-input" form="ledger-manual-transaction-form" type="text" name="detail" maxlength="4000" placeholder="填写明细" required></td>
|
||||
<td><span class="ledger-source-tag">手工录入</span></td>
|
||||
@ -822,6 +834,20 @@
|
||||
const tokenInput = manualTransactionForm.querySelector('[data-ledger-manual-token]');
|
||||
const saveButton = page.querySelector('[data-ledger-manual-save]');
|
||||
const cancelButton = page.querySelector('[data-ledger-manual-cancel]');
|
||||
const dateInput = page.querySelector('[data-ledger-manual-date]');
|
||||
const datePickerButton = page.querySelector('[data-ledger-manual-date-picker]');
|
||||
const accountInput = page.querySelector('[data-ledger-manual-account]');
|
||||
const accountOptions = page.querySelector('#ledger-manual-account-options');
|
||||
const accountShortValues = new Set(
|
||||
Array.from(accountOptions?.options || []).map((option) => option.value)
|
||||
);
|
||||
const validateManualAccount = () => {
|
||||
if (!accountInput) return false;
|
||||
const accountShort = accountInput.value.trim();
|
||||
const invalid = accountShort !== '' && !accountShortValues.has(accountShort);
|
||||
accountInput.setCustomValidity(invalid ? '请选择账户总表中的账户简称' : '');
|
||||
return !invalid;
|
||||
};
|
||||
const incomeInput = page.querySelector('[data-ledger-manual-income]');
|
||||
const expenseInput = page.querySelector('[data-ledger-manual-expense]');
|
||||
const summaryCount = page.querySelector('[data-ledger-transaction-summary-count]');
|
||||
@ -858,6 +884,7 @@
|
||||
|
||||
const resetManualDraft = (nextToken = null) => {
|
||||
manualTransactionForm.reset();
|
||||
accountInput?.setCustomValidity('');
|
||||
if (nextToken) tokenInput.dataset.currentToken = nextToken;
|
||||
if (tokenInput?.dataset.currentToken) tokenInput.value = tokenInput.dataset.currentToken;
|
||||
syncManualDirection();
|
||||
@ -895,11 +922,39 @@
|
||||
|
||||
manualTransactionTrigger.addEventListener('click', () => showManualDraft(true));
|
||||
cancelButton?.addEventListener('click', () => resetManualDraft());
|
||||
accountInput?.addEventListener('input', () => accountInput.setCustomValidity(''));
|
||||
accountInput?.addEventListener('change', validateManualAccount);
|
||||
accountInput?.addEventListener('blur', validateManualAccount);
|
||||
dateInput?.addEventListener('click', () => {
|
||||
if (typeof dateInput.showPicker !== 'function') return;
|
||||
try { dateInput.showPicker(); } catch (error) { /* 已经打开时忽略 */ }
|
||||
});
|
||||
datePickerButton?.addEventListener('click', () => {
|
||||
if (!dateInput) return;
|
||||
dateInput.focus({ preventScroll: true });
|
||||
if (typeof dateInput.showPicker === 'function') {
|
||||
try {
|
||||
dateInput.showPicker();
|
||||
return;
|
||||
} catch (error) { /* 回退到输入框原生点击 */ }
|
||||
}
|
||||
dateInput.click();
|
||||
});
|
||||
incomeInput?.addEventListener('input', () => syncManualDirection(incomeInput));
|
||||
expenseInput?.addEventListener('input', () => syncManualDirection(expenseInput));
|
||||
|
||||
manualTransactionForm.addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
const accountShort = accountInput?.value.trim() || '';
|
||||
if (!accountShortValues.has(accountShort)) {
|
||||
accountInput?.setCustomValidity('请选择账户总表中的账户简称');
|
||||
accountInput?.reportValidity();
|
||||
return;
|
||||
}
|
||||
if (accountInput) {
|
||||
accountInput.value = accountShort;
|
||||
accountInput.setCustomValidity('');
|
||||
}
|
||||
if (!manualTransactionForm.reportValidity()) return;
|
||||
const income = Number(incomeInput?.value || 0);
|
||||
const expense = Number(expenseInput?.value || 0);
|
||||
|
||||
@ -75,7 +75,12 @@ class FinanceLedgerManualTransactionTest extends FeatureTestCase
|
||||
->assertSee('新增手工明细')
|
||||
->assertSee('data-ledger-manual-trigger', false)
|
||||
->assertSee('data-ledger-manual-draft', false)
|
||||
->assertSee('data-ledger-manual-date-picker', false)
|
||||
->assertSee('calendar_today', false)
|
||||
->assertSee('name="account_short"', false)
|
||||
->assertSee('list="ledger-manual-account-options"', false)
|
||||
->assertSee('data-ledger-manual-account', false)
|
||||
->assertSee('输入账户简称', false)
|
||||
->assertSee('手工账户甲 · 手工测试公司甲', false)
|
||||
->assertSee('name="income"', false)
|
||||
->assertSee('name="expense"', false)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user