import { DropdownDirective } from '../shared/dropdown.directive'; import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, OnInit, inject, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { RouterLink } from '@angular/router'; import { Building2, ChevronLeft, ChevronRight, Eye, Pencil, Plus, RefreshCw, Search, Trash2, Users, X } from 'lucide-angular'; import { LucideAngularModule } from 'lucide-angular'; import { StorePage, StoreSummary } from '../admin.models'; import { OperationsService } from '../operations.service'; @Component({ selector: 'app-operations-stores', standalone: true, imports: [DropdownDirective, CommonModule, FormsModule, RouterLink, LucideAngularModule], templateUrl: './operations-stores.component.html', styleUrls: ['./operations-professional.scss', './operations-stores.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class OperationsStoresComponent implements OnInit { readonly page = signal(null); readonly query = signal(''); readonly status = signal('all'); readonly loading = signal(true); readonly saving = signal(false); readonly error = signal(''); readonly message = signal(''); readonly drawerOpen = signal(false); readonly editing = signal(null); readonly deleteArmed = signal(false); readonly username = signal(''); readonly password = signal(''); readonly storeName = signal(''); readonly contactName = signal(''); readonly mobile = signal(''); readonly parentStoreId = signal(0); readonly disabled = signal(false); readonly reason = signal(''); readonly icons = { Building2, ChevronLeft, ChevronRight, Eye, Pencil, Plus, RefreshCw, Search, Trash2, Users, X }; private readonly operations = inject(OperationsService); ngOnInit(): void { void this.load(1); } async load(page = 1): Promise { this.loading.set(true); this.error.set(''); try { this.page.set(await this.operations.stores(page, 20, this.query(), { status: this.status() })); } catch (error) { this.error.set(error instanceof Error ? error.message : '门店数据加载失败'); } finally { this.loading.set(false); } } reset(): void { this.query.set(''); this.status.set('all'); void this.load(1); } pageCount(): number { return Math.max(1, Math.ceil((this.page()?.total || 0) / (this.page()?.pageSize || 20))); } availableParents() { const ownId = this.editing()?.userId || 0; return (this.page()?.parents || []).filter((store) => store.userId !== ownId); } openCreate(): void { this.editing.set(null); this.username.set(''); this.password.set(''); this.storeName.set(''); this.contactName.set(''); this.mobile.set(''); this.parentStoreId.set(0); this.disabled.set(false); this.reason.set('新增门店'); this.deleteArmed.set(false); this.error.set(''); this.drawerOpen.set(true); } openEdit(row: StoreSummary, deleteMode = false): void { if (row.readOnly) { this.message.set('该门店来自旧系统实时数据,持续同步落库前暂不允许在新后台单边修改。'); return; } this.editing.set(row); this.username.set(row.username); this.password.set(''); this.storeName.set(row.storeName); this.contactName.set(row.contactName || ''); this.mobile.set(row.mobile || ''); this.parentStoreId.set(row.parentStoreId || 0); this.disabled.set(row.status === 'disabled'); this.reason.set(''); this.deleteArmed.set(deleteMode); this.error.set(''); this.drawerOpen.set(true); } closeDrawer(): void { this.drawerOpen.set(false); this.deleteArmed.set(false); } async save(): Promise { const editing = this.editing(); if (!this.username().trim() || !this.storeName().trim() || !this.reason().trim()) { this.error.set('登录账号、门店名称和操作原因必填'); return; } if (!editing && !this.password()) { this.error.set('新增门店必须设置初始密码'); return; } this.saving.set(true); this.error.set(''); try { await this.operations.mutate( editing ? 'ops/stores/update' : 'ops/stores/create', editing?.objectId || '', this.reason(), { username: this.username().trim(), password: this.password(), storeName: this.storeName().trim(), contactName: this.contactName().trim(), mobile: this.mobile().trim(), parentStoreId: this.parentStoreId(), disabled: this.disabled(), }, editing?.updatedAt || '', ); this.message.set(editing ? '门店资料已更新' : '门店已新增'); this.closeDrawer(); await this.load(editing ? this.page()?.page || 1 : 1); } catch (error) { this.error.set(error instanceof Error ? error.message : '门店资料保存失败'); } finally { this.saving.set(false); } } async remove(): Promise { const editing = this.editing(); if (!editing) return; if (!this.reason().trim()) { this.error.set('删除前必须填写操作原因'); return; } if (!this.deleteArmed()) { this.deleteArmed.set(true); return; } this.saving.set(true); this.error.set(''); try { await this.operations.mutate('ops/stores/delete', editing.objectId, this.reason(), {}, editing.updatedAt); this.message.set('门店已删除,历史业务数据仍保留'); this.closeDrawer(); await this.load(1); } catch (error) { this.error.set(error instanceof Error ? error.message : '门店删除失败'); } finally { this.saving.set(false); } } }