3 KiB
Task Record: Batch Edit Clients
Date: 2026-04-26 Related Module: Client management (web/service, web/controller, web/html) Change Type: Add
Background
Users previously had to edit each client individually to change shared settings (flow, limit IP, total GB, expiry time, enable state, Telegram ID, comment, reset period). This was time-consuming when managing many clients in an inbound.
Changes
Added batch multi-select and batch editing for clients in the inbound expanded view:
Backend:
- New
BatchUpdateInboundClientsservice method inweb/service/inbound.go- updates multiple clients' common fields in one transaction, syncs client_traffics table (total, expiry_time, enable, reset, tg_id) and Xray API (enable/disable) - New
BatchUpdateInboundClientsForUserauthorization wrapper - New
POST /panel/api/inbounds/batchUpdateClientsAPI route inweb/controller/inbound.go - Added
toInt64helper for JSON number type conversion
Frontend:
- New
client_batch_edit_modal.htmlmodal for batch editing common fields (enable, security, flow, limitIP, totalGB, expiryTime, delayedStart, reset, tgId, comment) with "keep unchanged" defaults - Modified
inbounds.htmlexpanded row: added row-selection to client table, batch action bar (batch edit, enable/disable, reset traffic, delete, deselect) - Added
clientSelectionreactive state and helper methods (getClientRowKey,getClientRowSelection,getSelectedClients,openBatchEditClient,batchEnableClient,batchResetClientTraffic,batchDelClient,clearClientSelection)
Translations:
- Added keys to
translate.en_US.tomlandtranslate.zh_CN.toml: batchEdit, batchEditAlert, batchKeep, batchEditNoFields, batchDeselect, batchDeleteLastClient, selected
Fields explicitly NOT batch-editable (enforced both frontend and backend):
- email (unique identifier for traffic tracking)
- id (protocol-specific client UUID)
- subId (subscription identifier)
- password (Trojan client password)
Impact
Affected files:
web/service/inbound.go(+~210 lines)web/controller/inbound.go(+~30 lines)web/html/inbounds.html(~+90 lines in methods, +15 lines in template)web/html/modals/client_batch_edit_modal.html(new, 209 lines)web/translation/translate.en_US.toml(+8 keys)web/translation/translate.zh_CN.toml(+8 keys)
No database schema changes. No config changes. No breaking API changes (new route only).
Verification
go build ./...- passesCGO_ENABLED=1 go build- passesgo vet ./...- passesgofmt -d- no formatting issues
Not verified: runtime integration testing (requires running panel with Xray and clients).
Risks And Follow-Up
- Batch delete does not prevent deleting the LAST client (only warns when trying to delete ALL remaining). The individual delete button already shows/hides based on
isRemovable(). - If the Xray API call fails during batch enable/disable, the service returns
needRestart=truewhich triggers Xray restart by the periodic check. - The batch edit modal resets all field values when reopened; no persistence across invocations.