Просмотр исходного кода

style(admin): unify payroll month picker and tabs

彭峰 1 месяц назад
Родитель
Сommit
c4f65418a5

Разница между файлами не показана из-за своего большого размера
+ 0 - 1
projects/xiaoshu-admin/src/app/pages/operations-payroll.component.html


+ 137 - 6
projects/xiaoshu-admin/src/app/pages/operations-payroll.component.scss

@@ -47,9 +47,9 @@
 }
 
 .payroll-tabs {
-  display: inline-flex;
-  max-width: 100%;
-  overflow-x: auto;
+  display: grid;
+  grid-template-columns: repeat(4, minmax(0, 1fr));
+  width: 100%;
   gap: 12px;
   margin: 0 0 18px;
   padding: 8px;
@@ -61,7 +61,7 @@
 
 .payroll-tabs button {
   display: inline-flex;
-  flex-shrink: 0;
+  min-width: 0;
   white-space: nowrap;
   min-height: 44px;
   align-items: center;
@@ -100,6 +100,127 @@
   min-width: 0;
 }
 
+.month-picker-field {
+  position: relative;
+  display: grid;
+  gap: 6px;
+  min-width: 0;
+  color: #62716c;
+  font-size: 12px;
+  font-weight: 700;
+}
+
+.month-picker-trigger {
+  display: grid;
+  grid-template-columns: auto minmax(0, 1fr) auto;
+  width: 100%;
+  height: 46px;
+  align-items: center;
+  gap: 8px;
+  padding: 9px 11px;
+  border: 1px solid #d7e1dd;
+  border-radius: 12px;
+  color: #486058;
+  background: #fff;
+  text-align: left;
+  cursor: pointer;
+}
+
+.month-picker-trigger strong {
+  overflow: hidden;
+  color: #2a3c36;
+  font-size: 13px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.month-picker-trigger:hover,
+.month-picker-trigger.active,
+.month-picker-trigger:focus-visible {
+  border-color: #7fae9f;
+  outline: 0;
+  background: #fbfefd;
+  box-shadow: 0 0 0 3px rgba(31, 128, 102, .11);
+}
+
+.picker-chevron { color: #657972; }
+
+.month-calendar-popover {
+  position: absolute;
+  z-index: 85;
+  top: calc(100% + 9px);
+  left: 0;
+  width: 310px;
+  padding: 14px;
+  border: 1px solid #d9e5e0;
+  border-radius: 16px;
+  background: #fff;
+  box-shadow: 0 20px 55px rgba(24, 62, 49, .2);
+}
+
+.month-calendar-popover header {
+  display: grid;
+  grid-template-columns: 34px 1fr 34px;
+  align-items: center;
+  margin-bottom: 12px;
+}
+
+.month-calendar-popover header strong {
+  color: #263b34;
+  font-size: 14px;
+  text-align: center;
+}
+
+.month-calendar-popover button {
+  border: 0;
+  border-radius: 9px;
+  color: #415a51;
+  background: transparent;
+  cursor: pointer;
+}
+
+.month-calendar-popover button:hover,
+.month-calendar-popover button:focus-visible {
+  outline: 0;
+  color: #176c55;
+  background: #edf7f3;
+}
+
+.month-calendar-popover header button {
+  display: grid;
+  width: 34px;
+  height: 34px;
+  place-items: center;
+}
+
+.month-grid {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  gap: 7px;
+}
+
+.month-grid button {
+  min-height: 39px;
+  font-size: 13px;
+  font-weight: 700;
+}
+
+.month-grid button.selected {
+  color: #fff;
+  background: #1f8066;
+  box-shadow: 0 6px 14px rgba(31, 128, 102, .2);
+}
+
+.month-calendar-popover footer {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 10px;
+  padding-top: 10px;
+  border-top: 1px solid #e6eeeb;
+}
+
+.month-calendar-popover footer button { min-height: 34px; padding: 0 10px; font-weight: 700; }
+
 .payroll-toolbar input,
 .payroll-toolbar select {
   height: 46px;
@@ -411,10 +532,12 @@
   }
 
   .payroll-tabs {
-    display: flex;
-    width: 100%;
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+    gap: 6px;
   }
 
+  .payroll-tabs button { min-height: 42px; padding: 0 10px; }
+
   .payroll-toolbar {
     grid-template-columns: 1fr;
     padding: 15px;
@@ -425,6 +548,14 @@
     grid-column: auto;
   }
 
+  .month-calendar-popover {
+    position: fixed;
+    top: 50%;
+    left: 50%;
+    width: min(330px, calc(100vw - 28px));
+    transform: translate(-50%, -50%);
+  }
+
   .filter-actions > button {
     flex: 1;
   }

+ 3 - 0
projects/xiaoshu-admin/src/app/pages/operations-payroll.component.spec.ts

@@ -63,6 +63,9 @@ describe('payroll interactions', () => {
  it('reset keeps month and clears search, store and the teacher deep link',async()=>{
   component.month.set('2026-08');component.storeId.set(10);component.search.set('老师');component.rewardCoachId.set(30);component.openRewards();await component.resetFilters();expect(component.rewardFilters()).toEqual(jasmine.objectContaining({month:'2026-08',storeId:0,search:'',coachId:0,resetRevision:1}));
  });
+ it('selects payroll months through the shared calendar-style picker',()=>{
+  component.month.set('2026-09');const event=new Event('click');spyOn(event,'stopPropagation');component.toggleMonthPicker(event);expect(component.monthPickerOpen()).toBeTrue();expect(component.monthPickerYear()).toBe(2026);component.shiftMonthPickerYear(1,event);component.selectMonth(0);expect(component.month()).toBe('2027-01');expect(component.monthLabel()).toBe('2027年1月');expect(component.monthPickerOpen()).toBeFalse();
+ });
  it('retains adjustment request identity after a lost response and sends batch version',async()=>{
   component.detail.set({objectId:'batch',version:3,status:'draft'} as never);component.adjustmentCoachId.set(30);component.adjustmentAmount.set(10);component.adjustmentReason.set('补计工资');service.mutate.and.rejectWith(new Error('网络中断'));
   await component.addAdjustment();await component.addAdjustment();const calls=service.mutate.calls.allArgs();expect(calls.length).toBe(2);expect(calls[0][5]).toBe(calls[1][5]);expect(calls[0][3]).toEqual(jasmine.objectContaining({version:3,amount:10,coachId:30}));

Разница между файлами не показана из-за своего большого размера
+ 2 - 2
projects/xiaoshu-admin/src/app/pages/operations-payroll.component.ts


Некоторые файлы не были показаны из-за большого количества измененных файлов