function controlState(state, key) { state.tableFilters ||= {}; return state.tableFilters[key] ||= { query: '', status: 'all', filters: {} }; } function searchable(value) { if (value == null) return ''; if (Array.isArray(value)) return value.map(searchable).join(' '); if (typeof value === 'object') return Object.values(value).map(searchable).join(' '); return String(value); } function statusTokens(item) { const tokens = [item?.status, item?.paymentStatus]; if (typeof item?.active === 'boolean') tokens.push(item.active ? 'active approved' : 'inactive disabled closed'); if (typeof item?.published === 'boolean') tokens.push(item.published ? 'published visible' : 'draft hidden'); if (typeof item?.qualified === 'boolean') tokens.push(item.qualified ? 'qualified' : 'unqualified'); if (typeof item?.confirmed === 'boolean') tokens.push(item.confirmed ? (item.eligible ? 'confirmed eligible' : 'confirmed ineligible') : 'unconfirmed'); return tokens.filter(Boolean).join(' ').toLowerCase(); } export function filterTableItems(state, items, key) { const control = controlState(state, key); const query = String(control.query || '').trim().toLocaleLowerCase('zh-CN'); const status = String(control.status || 'all').toLowerCase(); const filters = Object.values(control.filters || {}).filter(Boolean).map(value => String(value).toLocaleLowerCase('zh-CN')); return (items || []).filter(item => { const haystack = searchable(item).toLocaleLowerCase('zh-CN'); if (query && !query.split(/\s+/).every(word => haystack.includes(word))) return false; if (status !== 'all' && !statusTokens(item).split(/\s+/).includes(status)) return false; return filters.every(value => haystack.includes(value)); }); } export function setTableControl(state, key, patch) { const current = controlState(state, key); Object.assign(current, patch); if (patch.filters) current.filters = { ...(current.filters || {}), ...patch.filters }; if (state.tablePages?.[key]) state.tablePages[key].page = 1; } export function getTableControl(state, key) { return controlState(state, key); }