<template>
  <div v-loading="pageLoading" class="NCC-common-layout attendance-setting-page">
    <div class="NCC-common-layout-center">
      <div class="NCC-common-layout-main page-shell">
        <aside class="page-side">
          <div class="summary-panel">
            <div class="summary-panel__eyebrow">考勤配置总览</div>
            <h2 class="summary-panel__title">考勤设置中心</h2>
            <p class="summary-panel__desc">
              班次、应休已拆分维护：考勤分组管上下班时间；应休分组管月应休与解锁。人员在用户资料中绑定考勤分组与应休分组。
            </p>

            <div class="summary-metrics">
              <div class="summary-metric">
                <div class="summary-metric__label">公休日期</div>
                <div class="summary-metric__value">{{ summaryCards.holidayCount }}</div>
                <div class="summary-metric__hint">已维护公休/节假日条数</div>
              </div>
              <div class="summary-metric">
                <div class="summary-metric__label">考勤分组</div>
                <div class="summary-metric__value">{{ summaryCards.groupCount }}</div>
                <div class="summary-metric__hint">其中启用 {{ summaryCards.enabledGroupCount }} 个</div>
              </div>
              <div class="summary-metric">
                <div class="summary-metric__label">应休分组</div>
                <div class="summary-metric__value">{{ summaryCards.restGroupCount }}</div>
                <div class="summary-metric__hint">其中启用 {{ summaryCards.enabledRestGroupCount }} 个</div>
              </div>
              <div class="summary-metric">
                <div class="summary-metric__label">假期规则</div>
                <div class="summary-metric__value">{{ summaryCards.leaveRuleCount }}</div>
                <div class="summary-metric__hint">婚假 / 丧假 / 年假 / 产假 / 额外假期</div>
              </div>
              <div class="summary-metric">
                <div class="summary-metric__label">扣款规则</div>
                <div class="summary-metric__value">{{ summaryCards.deductRuleCount }}</div>
                <div class="summary-metric__hint">迟到早退 / 缺卡 / 旷工</div>
              </div>
            </div>
          </div>

          <div class="summary-card">
            <div class="summary-card__title">基础扣款概览</div>
            <div class="summary-detail">
              <div class="summary-detail__item">
                <span class="summary-detail__label">请假扣款</span>
                <span class="summary-detail__value">{{ baseInfo.leaveDeductDailySalaryRate }} × 日薪</span>
              </div>
              <div class="summary-detail__item">
                <span class="summary-detail__label">病假扣款</span>
                <span class="summary-detail__value">{{ baseInfo.sickLeaveDeductDailySalaryRate }} × 日薪</span>
              </div>
              <div class="summary-detail__item">
                <span class="summary-detail__label">最后更新</span>
                <span class="summary-detail__value">{{ baseInfo.lastModifyTime || '无' }}</span>
              </div>
              <div class="summary-detail__item">
                <span class="summary-detail__label">更新人</span>
                <span class="summary-detail__value">{{ baseInfo.lastModifyUserName || '无' }}</span>
              </div>
            </div>
          </div>
        </aside>

        <section class="page-main">
          <div class="page-main__toolbar">
            <div class="page-main__title">
              <i class="el-icon-s-operation page-main__title-icon" aria-hidden="true" />
              <span class="page-main__title-text">当前模块</span>
              <el-tag type="primary" effect="plain" size="small" class="page-main__tab-tag">{{ activeTabLabel
              }}</el-tag>
            </div>
            <div class="page-main__actions">
              <el-button size="small" icon="el-icon-refresh-right" @click="initData">重新加载</el-button>
            </div>
          </div>

          <div class="page-main__content">
            <el-tabs v-model="activeTab" class="setting-tabs NCC-el_tabs" @tab-click="handleTabChange">
              <el-tab-pane label="基础设置" name="base">
                <div class="tab-panel">
                  <el-card v-loading="baseInfoLoading" class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">基础扣款设置</div>
                        <div class="section-card__desc">请假与病假的扣款倍率独立维护，并保留每次调整历史。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button size="mini" :disabled="!baseInfo.id" @click="openBaseHistory">历史记录</el-button>
                        <el-button type="primary" size="mini" @click="openBaseDialog">编辑设置</el-button>
                      </div>
                    </div>

                    <div class="base-card__grid">
                      <div class="base-card__item">
                        <div class="base-card__label">请假扣款</div>
                        <div class="base-card__value">{{ baseInfo.leaveDeductDailySalaryRate }}</div>
                        <div class="base-card__hint">按“天数 × 日薪 × 倍率”计算</div>
                      </div>
                      <div class="base-card__item">
                        <div class="base-card__label">病假扣款</div>
                        <div class="base-card__value">{{ baseInfo.sickLeaveDeductDailySalaryRate }}</div>
                        <div class="base-card__hint">按“天数 × 日薪 × 倍率”计算</div>
                      </div>
                      <div class="base-card__item base-card__item--wide">
                        <div class="base-card__label">备注</div>
                        <div class="base-card__remark">{{ baseInfo.remark || '无' }}</div>
                      </div>
                    </div>
                  </el-card>
                </div>
              </el-tab-pane>

              <el-tab-pane label="公休时间" name="holiday">
                <div class="tab-panel">
                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">公休时间设置</div>
                        <div class="section-card__desc">按年份维护全员公休时间，删除为逻辑删除并写入历史。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini" @click="openConfigDialog('holiday')">新增日期</el-button>
                      </div>
                    </div>

                    <div class="section-filter">
                      <el-select v-model="moduleState.holiday.query.year" size="small" class="section-filter__year"
                        @change="handleModuleSearch('holiday')">
                        <el-option v-for="item in yearOptions" :key="item" :label="`${item}年`" :value="item" />
                      </el-select>
                      <el-input v-model.trim="moduleState.holiday.query.keyword" size="small"
                        class="section-filter__keyword" clearable placeholder="节假日名称 / 备注"
                        @keyup.enter.native="handleModuleSearch('holiday')" />
                      <el-button type="primary" size="small" icon="el-icon-search"
                        @click="handleModuleSearch('holiday')">查询</el-button>
                      <el-button size="small" icon="el-icon-refresh-right"
                        @click="handleModuleReset('holiday')">重置</el-button>
                    </div>

                    <NCC-table v-loading="moduleState.holiday.loading" :data="moduleState.holiday.list" border
                      size="mini" height="460">
                      <el-table-column prop="holidayDate" label="公休日期" width="140" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--primary" :title="scope.row.holidayDate">
                            <i class="el-icon-date" />
                            <span>{{ scope.row.holidayDate || '无' }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="holidayName" label="节假日名称" min-width="180" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--success" :title="scope.row.holidayName || '无'">
                            <i class="el-icon-star-off" />
                            <span>{{ scope.row.holidayName || '无' }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="remark" label="备注" min-width="220" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.remark || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="210" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text" @click="openConfigDialog('holiday', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('holiday', scope.row, buildHolidayTitle(scope.row))">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('holiday', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                    <div v-if="!moduleState.holiday.loading && !moduleState.holiday.list.length" class="section-empty">
                      <el-empty :image-size="60" description="当前筛选条件下暂无公休时间配置" />
                    </div>
                    <pagination :hidden="!moduleState.holiday.pagination.total"
                      :total="moduleState.holiday.pagination.total" :page.sync="moduleState.holiday.query.currentPage"
                      :limit.sync="moduleState.holiday.query.pageSize"
                      @pagination="() => loadModule('holiday', true)" />
                  </el-card>
                </div>
              </el-tab-pane>

              <el-tab-pane label="考勤分组" name="group">
                <div class="tab-panel">
                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">考勤分组</div>
                        <div class="section-card__desc">仅维护上下班时间及启用状态；月应休、半天拆分、解锁规则请在「应休分组」中配置并在人员资料中绑定。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini" @click="openConfigDialog('group')">新增分组</el-button>
                      </div>
                    </div>

                    <div class="section-filter">
                      <el-input v-model.trim="moduleState.group.query.keyword" size="small"
                        class="section-filter__keyword" clearable placeholder="分组名称 / 备注"
                        @keyup.enter.native="handleModuleSearch('group')" />
                      <el-button type="primary" size="small" icon="el-icon-search"
                        @click="handleModuleSearch('group')">查询</el-button>
                      <el-button size="small" icon="el-icon-refresh-right"
                        @click="handleModuleReset('group')">重置</el-button>
                    </div>

                    <NCC-table v-loading="moduleState.group.loading" :data="moduleState.group.list" border size="mini"
                      height="460">
                      <el-table-column prop="groupName" label="分组名称" min-width="150" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--primary" :title="scope.row.groupName || '无'">
                            <i class="el-icon-s-grid" />
                            <span>{{ scope.row.groupName || '无' }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="workStartTime" label="上班时间" width="110" align="left" />
                      <el-table-column prop="workEndTime" label="下班时间" width="110" align="left" />
                      <el-table-column label="状态" width="90" align="left">
                        <template slot-scope="scope">
                          <el-tag :type="Number(scope.row.isEnabled) === 1 ? 'success' : 'info'" size="mini">
                            {{ Number(scope.row.isEnabled) === 1 ? '启用' : '停用' }}
                          </el-tag>
                        </template>
                      </el-table-column>
                      <el-table-column prop="remark" label="备注" min-width="180" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.remark || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="300" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text" @click="showGroupUsers(scope.row)">成员</el-button>
                          <el-button type="text" @click="openConfigDialog('group', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('group', scope.row, scope.row.groupName)">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('group', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                    <div v-if="!moduleState.group.loading && !moduleState.group.list.length" class="section-empty">
                      <el-empty :image-size="60" description="暂无考勤分组配置" />
                    </div>
                    <pagination :hidden="!moduleState.group.pagination.total"
                      :total="moduleState.group.pagination.total" :page.sync="moduleState.group.query.currentPage"
                      :limit.sync="moduleState.group.query.pageSize" @pagination="() => loadModule('group', true)" />
                  </el-card>
                </div>
              </el-tab-pane>

              <el-tab-pane label="应休分组" name="restGroup">
                <div class="tab-panel">
                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">应休分组</div>
                        <div class="section-card__desc">维护月应休、可拆分半天、解锁周期；人员在「用户管理」中绑定应休分组。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini" @click="openRestGroupDialog()">新增应休分组</el-button>
                      </div>
                    </div>

                    <div class="section-filter">
                      <el-input v-model.trim="moduleState.restGroup.query.keyword" size="small"
                        class="section-filter__keyword" clearable placeholder="分组名称 / 备注"
                        @keyup.enter.native="handleModuleSearch('restGroup')" />
                      <el-button type="primary" size="small" icon="el-icon-search"
                        @click="handleModuleSearch('restGroup')">查询</el-button>
                      <el-button size="small" icon="el-icon-refresh-right"
                        @click="handleModuleReset('restGroup')">重置</el-button>
                    </div>

                    <NCC-table v-loading="moduleState.restGroup.loading" :data="moduleState.restGroup.list" border
                      size="mini" height="460">
                      <el-table-column prop="groupName" label="分组名称" min-width="140" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--success" :title="scope.row.groupName || '无'">
                            <i class="el-icon-present" />
                            <span>{{ scope.row.groupName || '无' }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="monthlyRestDays" label="月应休天数" width="110" align="left" />
                      <el-table-column prop="halfDaySplitRestDays" label="可拆半天天数" width="120" align="left" />
                      <el-table-column label="解锁规则" min-width="160" align="left">
                        <template slot-scope="scope">
                          <span v-if="scope.row.restUnlockCycle > 0" class="cell-with-icon cell-with-icon--primary">
                            <i class="el-icon-unlock" />
                            <span>每上满 {{ scope.row.restUnlockCycle }} 天解锁 1 天</span>
                          </span>
                          <span v-else style="color: #909399;">不启用</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="状态" width="90" align="left">
                        <template slot-scope="scope">
                          <el-tag :type="Number(scope.row.isEnabled) === 1 ? 'success' : 'info'" size="mini">
                            {{ Number(scope.row.isEnabled) === 1 ? '启用' : '停用' }}
                          </el-tag>
                        </template>
                      </el-table-column>
                      <el-table-column prop="remark" label="备注" min-width="160" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.remark || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="160" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text" @click="openRestGroupDialog(scope.row)">编辑</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('restGroup', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                    <div v-if="!moduleState.restGroup.loading && !moduleState.restGroup.list.length" class="section-empty">
                      <el-empty :image-size="60" description="暂无应休分组" />
                    </div>
                    <pagination :hidden="!moduleState.restGroup.pagination.total"
                      :total="moduleState.restGroup.pagination.total"
                      :page.sync="moduleState.restGroup.query.currentPage"
                      :limit.sync="moduleState.restGroup.query.pageSize"
                      @pagination="() => loadModule('restGroup', true)" />
                  </el-card>
                </div>
              </el-tab-pane>

              <el-tab-pane label="假期规则" name="leave">
                <div class="tab-panel tab-panel--grid">
                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">婚假规则</div>
                        <div class="section-card__desc">按司龄区间单独维护婚假天数。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini"
                          @click="openConfigDialog('marriageLeaveRule')">新增规则</el-button>
                      </div>
                    </div>
                    <NCC-table v-loading="moduleState.marriageLeaveRule.loading"
                      :data="moduleState.marriageLeaveRule.list" border size="mini" height="320">
                      <el-table-column prop="minYears" label="最小司龄（含）" width="120" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--primary" :title="String(scope.row.minYears)">
                            <i class="el-icon-time" />
                            <span>{{ scope.row.minYears }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column label="最大司龄（不含）" width="130" align="left">
                        <template slot-scope="scope">
                          <span>{{ renderUpperValue(scope.row.maxYears, '年') }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="leaveDays" label="婚假天数" width="110" align="left" />
                      <el-table-column prop="remark" label="备注" min-width="160" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.remark || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="210" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text"
                            @click="openConfigDialog('marriageLeaveRule', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('marriageLeaveRule', scope.row, buildYearRangeTitle(scope.row, '婚假规则'))">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('marriageLeaveRule', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                  </el-card>

                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">丧假规则</div>
                        <div class="section-card__desc">支持直系/非直系亲属丧假天数配置。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini"
                          @click="openConfigDialog('funeralLeaveRule')">新增规则</el-button>
                      </div>
                    </div>
                    <NCC-table v-loading="moduleState.funeralLeaveRule.loading"
                      :data="moduleState.funeralLeaveRule.list" border size="mini" height="320">
                      <el-table-column prop="minYears" label="最小司龄（含）" width="120" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--primary" :title="String(scope.row.minYears)">
                            <i class="el-icon-time" />
                            <span>{{ scope.row.minYears }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column label="最大司龄（不含）" width="130" align="left">
                        <template slot-scope="scope">
                          <span>{{ renderUpperValue(scope.row.maxYears, '年') }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="directRelativeDays" label="直系亲属" width="100" align="left" />
                      <el-table-column prop="indirectRelativeDays" label="非直系亲属" width="110" align="left" />
                      <el-table-column prop="remark" label="备注" min-width="150" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.remark || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="210" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text" @click="openConfigDialog('funeralLeaveRule', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('funeralLeaveRule', scope.row, buildYearRangeTitle(scope.row, '丧假规则'))">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('funeralLeaveRule', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                  </el-card>

                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">年假规则</div>
                        <div class="section-card__desc">按司龄区间维护年假额度，支持无上限区间。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini"
                          @click="openConfigDialog('annualLeaveRule')">新增规则</el-button>
                      </div>
                    </div>
                    <NCC-table v-loading="moduleState.annualLeaveRule.loading" :data="moduleState.annualLeaveRule.list"
                      border size="mini" height="320">
                      <el-table-column prop="minYears" label="最小司龄（含）" width="120" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--success" :title="String(scope.row.minYears)">
                            <i class="el-icon-time" />
                            <span>{{ scope.row.minYears }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column label="最大司龄（不含）" width="130" align="left">
                        <template slot-scope="scope">
                          <span>{{ renderUpperValue(scope.row.maxYears, '年') }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="leaveDays" label="年假天数" width="110" align="left" />
                      <el-table-column prop="remark" label="备注" min-width="200" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.remark || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="210" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text" @click="openConfigDialog('annualLeaveRule', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('annualLeaveRule', scope.row, buildYearRangeTitle(scope.row, '年假规则'))">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('annualLeaveRule', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                  </el-card>

                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">产假规则</div>
                        <div class="section-card__desc">按司龄区间维护产假额度，支持无上限区间。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini"
                          @click="openConfigDialog('maternityLeaveRule')">新增规则</el-button>
                      </div>
                    </div>
                    <NCC-table v-loading="moduleState.maternityLeaveRule.loading"
                      :data="moduleState.maternityLeaveRule.list" border size="mini" height="320">
                      <el-table-column prop="minYears" label="最小司龄（含）" width="120" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--success" :title="String(scope.row.minYears)">
                            <i class="el-icon-time" />
                            <span>{{ scope.row.minYears }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column label="最大司龄（不含）" width="130" align="left">
                        <template slot-scope="scope">
                          <span>{{ renderUpperValue(scope.row.maxYears, '年') }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="leaveDays" label="产假天数" width="110" align="left" />
                      <el-table-column prop="remark" label="备注" min-width="200" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.remark || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="210" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text"
                            @click="openConfigDialog('maternityLeaveRule', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('maternityLeaveRule', scope.row, buildYearRangeTitle(scope.row, '产假规则'))">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('maternityLeaveRule', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                  </el-card>
                </div>
              </el-tab-pane>

              <el-tab-pane label="扣款规则" name="deduct">
                <div class="tab-panel tab-panel--grid">
                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">迟到 / 早退扣款规则</div>
                        <div class="section-card__desc">打卡接口会按此规则即时判断迟到、早退。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini" @click="openConfigDialog('lateRule')">新增规则</el-button>
                      </div>
                    </div>
                    <NCC-table v-loading="moduleState.lateRule.loading" :data="moduleState.lateRule.list" border
                      size="mini" height="320">
                      <el-table-column prop="minMinutes" label="最小分钟（含）" width="120" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--primary" :title="String(scope.row.minMinutes)">
                            <i class="el-icon-alarm-clock" />
                            <span>{{ scope.row.minMinutes }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column label="最大分钟（不含）" width="130" align="left">
                        <template slot-scope="scope">
                          <span>{{ renderUpperValue(scope.row.maxMinutes, '分钟') }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="扣款方式" width="120" align="left">
                        <template slot-scope="scope">
                          <span>{{ getDeductModeText(scope.row.deductMode) }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="deductValue" label="扣款值" width="100" align="left" />
                      <el-table-column prop="expressionText" label="展示说明" min-width="180" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.expressionText || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="210" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text" @click="openConfigDialog('lateRule', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('lateRule', scope.row, buildMinuteRangeTitle(scope.row, '迟到/早退规则'))">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('lateRule', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                  </el-card>

                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">忘记打卡扣款规则</div>
                        <div class="section-card__desc">支持 1-2 次、3-6 次、7 次及以上等阶梯规则。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini"
                          @click="openConfigDialog('missingCardRule')">新增规则</el-button>
                      </div>
                    </div>
                    <NCC-table v-loading="moduleState.missingCardRule.loading" :data="moduleState.missingCardRule.list"
                      border size="mini" height="320">
                      <el-table-column prop="minCount" label="最小次数（含）" width="120" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--primary" :title="String(scope.row.minCount)">
                            <i class="el-icon-document" />
                            <span>{{ scope.row.minCount }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column label="最大次数（不含）" width="130" align="left">
                        <template slot-scope="scope">
                          <span>{{ renderUpperValue(scope.row.maxCount, '次') }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="deductPerTime" label="每次扣款" width="110" align="left" />
                      <el-table-column prop="expressionText" label="展示说明" min-width="190" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.expressionText || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="210" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text" @click="openConfigDialog('missingCardRule', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('missingCardRule', scope.row, buildCountRangeTitle(scope.row, '缺卡规则'))">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('missingCardRule', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                  </el-card>

                  <el-card class="section-card section-card--full" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">旷工规则</div>
                        <div class="section-card__desc">支持扣款与视为自离两种处理方式。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini"
                          @click="openConfigDialog('absenteeismRule')">新增规则</el-button>
                      </div>
                    </div>
                    <NCC-table v-loading="moduleState.absenteeismRule.loading" :data="moduleState.absenteeismRule.list"
                      border size="mini" height="320">
                      <el-table-column prop="minDays" label="最小天数（含）" width="120" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--danger" :title="String(scope.row.minDays)">
                            <i class="el-icon-warning-outline" />
                            <span>{{ scope.row.minDays }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column label="最大天数（不含）" width="130" align="left">
                        <template slot-scope="scope">
                          <span>{{ renderUpperValue(scope.row.maxDays, '天') }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="处理方式" width="100" align="left">
                        <template slot-scope="scope">
                          <span>{{ getActionTypeText(scope.row.actionType) }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="扣款规则" min-width="170" align="left">
                        <template slot-scope="scope">
                          <span>{{ buildAbsenteeismDeductText(scope.row) }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="actionText" label="展示说明" min-width="180" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.actionText || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="210" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text" @click="openConfigDialog('absenteeismRule', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('absenteeismRule', scope.row, buildDecimalRangeTitle(scope.row, '旷工规则'))">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('absenteeismRule', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                  </el-card>
                </div>
              </el-tab-pane>

              <el-tab-pane label="特殊人员" name="special">
                <div class="tab-panel">
                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">免考勤人员</div>
                        <div class="section-card__desc">支持按员工单独设置生效区间与启用状态。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini" @click="openConfigDialog('exemptUser')">新增人员</el-button>
                      </div>
                    </div>

                    <div class="section-filter">
                      <el-input v-model.trim="moduleState.exemptUser.query.keyword" size="small"
                        class="section-filter__keyword" clearable placeholder="员工姓名 / 备注"
                        @keyup.enter.native="handleModuleSearch('exemptUser')" />
                      <el-button type="primary" size="small" icon="el-icon-search"
                        @click="handleModuleSearch('exemptUser')">查询</el-button>
                      <el-button size="small" icon="el-icon-refresh-right"
                        @click="handleModuleReset('exemptUser')">重置</el-button>
                    </div>

                    <NCC-table v-loading="moduleState.exemptUser.loading" :data="moduleState.exemptUser.list" border
                      size="mini" height="460">
                      <el-table-column prop="userName" label="员工" min-width="150" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--primary" :title="scope.row.userName || '无'">
                            <i class="el-icon-user" />
                            <span>{{ scope.row.userName || '无' }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="startDate" label="开始日期" width="130" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.startDate || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="endDate" label="结束日期" width="130" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.endDate || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="状态" width="90" align="left">
                        <template slot-scope="scope">
                          <el-tag :type="Number(scope.row.isEnabled) === 1 ? 'success' : 'info'" size="mini">
                            {{ Number(scope.row.isEnabled) === 1 ? '启用' : '停用' }}
                          </el-tag>
                        </template>
                      </el-table-column>
                      <el-table-column prop="remark" label="备注" min-width="180" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.remark || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="210" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text" @click="openConfigDialog('exemptUser', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('exemptUser', scope.row, scope.row.userName)">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('exemptUser', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                    <div v-if="!moduleState.exemptUser.loading && !moduleState.exemptUser.list.length"
                      class="section-empty">
                      <el-empty :image-size="60" description="暂无免考勤人员配置" />
                    </div>
                    <pagination :hidden="!moduleState.exemptUser.pagination.total"
                      :total="moduleState.exemptUser.pagination.total"
                      :page.sync="moduleState.exemptUser.query.currentPage"
                      :limit.sync="moduleState.exemptUser.query.pageSize"
                      @pagination="() => loadModule('exemptUser', true)" />
                  </el-card>
                </div>
              </el-tab-pane>

              <el-tab-pane label="额外假期" name="extraLeave">
                <div class="tab-panel">
                  <el-card class="section-card" shadow="never">
                    <div slot="header" class="section-card__header">
                      <div>
                        <div class="section-card__title">额外假期</div>
                        <div class="section-card__desc">用于配置旅游奖励假、年会抽奖假等额外休假天数。</div>
                      </div>
                      <div class="section-card__actions">
                        <el-button type="primary" size="mini" @click="openConfigDialog('extraLeave')">新增额外假期</el-button>
                      </div>
                    </div>

                    <div class="section-filter">
                      <el-select v-model="moduleState.extraLeave.query.year" size="small" class="section-filter__year"
                        @change="handleModuleSearch('extraLeave')">
                        <el-option v-for="item in yearOptions" :key="item" :label="`${item}年`" :value="item" />
                      </el-select>
                      <el-input v-model.trim="moduleState.extraLeave.query.keyword" size="small"
                        class="section-filter__keyword" clearable placeholder="员工姓名 / 假期名称 / 备注"
                        @keyup.enter.native="handleModuleSearch('extraLeave')" />
                      <el-button type="primary" size="small" icon="el-icon-search"
                        @click="handleModuleSearch('extraLeave')">查询</el-button>
                      <el-button size="small" icon="el-icon-refresh-right"
                        @click="handleModuleReset('extraLeave')">重置</el-button>
                    </div>

                    <NCC-table v-loading="moduleState.extraLeave.loading" :data="moduleState.extraLeave.list" border
                      size="mini" height="460">
                      <el-table-column prop="userName" label="员工" min-width="140" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--primary" :title="scope.row.userName || '无'">
                            <i class="el-icon-user" />
                            <span>{{ scope.row.userName || '无' }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="leaveName" label="假期名称" min-width="160" align="left">
                        <template slot-scope="scope">
                          <span class="cell-with-icon cell-with-icon--success" :title="scope.row.leaveName || '无'">
                            <i class="el-icon-present" />
                            <span>{{ scope.row.leaveName || '无' }}</span>
                          </span>
                        </template>
                      </el-table-column>
                      <el-table-column prop="grantYear" label="归属年份" width="100" align="left" />
                      <el-table-column prop="extraDays" label="额外天数" width="100" align="left" />
                      <el-table-column label="状态" width="90" align="left">
                        <template slot-scope="scope">
                          <el-tag :type="Number(scope.row.isEnabled) === 1 ? 'success' : 'info'" size="mini">
                            {{ Number(scope.row.isEnabled) === 1 ? '启用' : '停用' }}
                          </el-tag>
                        </template>
                      </el-table-column>
                      <el-table-column prop="remark" label="备注" min-width="180" align="left">
                        <template slot-scope="scope">
                          <span>{{ scope.row.remark || '无' }}</span>
                        </template>
                      </el-table-column>
                      <el-table-column label="操作" width="210" align="left" fixed="right">
                        <template slot-scope="scope">
                          <el-button type="text" @click="openConfigDialog('extraLeave', scope.row)">编辑</el-button>
                          <el-button type="text"
                            @click="openHistory('extraLeave', scope.row, buildExtraLeaveTitle(scope.row))">历史</el-button>
                          <el-button type="text" class="danger-text"
                            @click="handleDelete('extraLeave', scope.row)">删除</el-button>
                        </template>
                      </el-table-column>
                    </NCC-table>
                    <div v-if="!moduleState.extraLeave.loading && !moduleState.extraLeave.list.length"
                      class="section-empty">
                      <el-empty :image-size="60" description="当前筛选条件下暂无额外假期配置" />
                    </div>
                    <pagination :hidden="!moduleState.extraLeave.pagination.total"
                      :total="moduleState.extraLeave.pagination.total"
                      :page.sync="moduleState.extraLeave.query.currentPage"
                      :limit.sync="moduleState.extraLeave.query.pageSize"
                      @pagination="() => loadModule('extraLeave', true)" />
                  </el-card>
                </div>
              </el-tab-pane>
            </el-tabs>
          </div>
        </section>
      </div>
    </div>

    <attendance-config-item-dialog ref="itemDialog" :deduct-mode-options="deductModeOptions"
      :action-type-options="actionTypeOptions" @submit="handleDialogSubmit" />
    <attendance-config-history-dialog ref="historyDialog" />
    <attendance-group-user-dialog ref="groupUserDialog" />
    <attendance-rest-group-dialog ref="restGroupDialog" @saved="onRestGroupSaved" />
  </div>
</template>

<script>
import {
  deleteAttendanceConfig,
  getAttendanceBaseInfo,
  getAttendanceConfigList,
  getAttendanceSettingOverview,
  saveAttendanceBaseInfo,
  saveAttendanceConfig
} from '@/api/extend/attendanceSetting'
import { deleteAttendanceRestGroup, getAttendanceRestGroupList } from '@/api/extend/attendanceRestGroup'
import AttendanceConfigHistoryDialog from './components/attendance-config-history-dialog'
import AttendanceConfigItemDialog from './components/attendance-config-item-dialog'
import AttendanceGroupUserDialog from './components/attendance-group-user-dialog'
import AttendanceRestGroupDialog from './components/attendance-rest-group-dialog'

const CURRENT_YEAR = new Date().getFullYear()
const YEAR_OPTIONS = Array.from({ length: 9 }).map((_, index) => CURRENT_YEAR + 4 - index)

const createPagination = pageSize => ({
  total: 0,
  currentPage: 1,
  pageSize
})

const createModuleState = ({ pageSize = 10, keyword = '', year = null } = {}) => ({
  loading: false,
  loaded: false,
  list: [],
  query: {
    currentPage: 1,
    pageSize,
    keyword,
    year
  },
  pagination: createPagination(pageSize)
})

export default {
  name: 'AttendanceSetting',
  components: {
    AttendanceConfigHistoryDialog,
    AttendanceConfigItemDialog,
    AttendanceGroupUserDialog,
    AttendanceRestGroupDialog
  },
  data() {
    return {
      activeTab: 'base',
      pageLoading: false,
      baseInfoLoading: false,
      yearOptions: YEAR_OPTIONS,
      baseInfo: {
        id: '',
        leaveDeductDailySalaryRate: 1,
        sickLeaveDeductDailySalaryRate: 1,
        remark: '',
        versionNo: 0,
        lastModifyTime: '',
        lastModifyUserName: ''
      },
      summaryCards: {
        holidayCount: 0,
        groupCount: 0,
        enabledGroupCount: 0,
        restGroupCount: 0,
        enabledRestGroupCount: 0,
        leaveRuleCount: 0,
        deductRuleCount: 0
      },
      moduleState: {
        holiday: createModuleState({ pageSize: 12, year: CURRENT_YEAR }),
        group: createModuleState({ pageSize: 10 }),
        restGroup: createModuleState({ pageSize: 10 }),
        marriageLeaveRule: createModuleState({ pageSize: 10 }),
        funeralLeaveRule: createModuleState({ pageSize: 10 }),
        annualLeaveRule: createModuleState({ pageSize: 10 }),
        maternityLeaveRule: createModuleState({ pageSize: 10 }),
        lateRule: createModuleState({ pageSize: 10 }),
        missingCardRule: createModuleState({ pageSize: 10 }),
        absenteeismRule: createModuleState({ pageSize: 10 }),
        exemptUser: createModuleState({ pageSize: 10 }),
        extraLeave: createModuleState({ pageSize: 10, year: CURRENT_YEAR })
      },
      deductModeOptions: [
        { label: '固定金额', value: 1 },
        { label: '日薪比例', value: 2 },
        { label: '日薪倍数', value: 3 },
        { label: '文本说明', value: 4 }
      ],
      actionTypeOptions: [
        { label: '扣款', value: 1 },
        { label: '视为自离', value: 2 }
      ]
    }
  },
  computed: {
    activeTabLabel() {
      return {
        base: '基础设置',
        holiday: '公休时间',
        group: '考勤分组',
        restGroup: '应休分组',
        leave: '假期规则',
        deduct: '扣款规则',
        special: '特殊人员',
        extraLeave: '额外假期'
      }[this.activeTab] || '考勤设置'
    }
  },
  created() {
    this.initData()
  },
  methods: {
    async initData() {
      this.pageLoading = true
      try {
        await Promise.all([this.loadOverview(), this.loadBaseInfo()])
        Object.keys(this.moduleState).forEach(key => {
          this.moduleState[key].loaded = false
        })
        await this.loadModulesByTab(this.activeTab, true)
      } finally {
        this.pageLoading = false
      }
    },
    async loadOverview() {
      const res = await getAttendanceSettingOverview()
      this.summaryCards = {
        ...this.summaryCards,
        ...(res.data || {})
      }
    },
    async loadBaseInfo() {
      this.baseInfoLoading = true
      try {
        const res = await getAttendanceBaseInfo()
        this.baseInfo = {
          ...this.baseInfo,
          ...(res.data || {})
        }
      } finally {
        this.baseInfoLoading = false
      }
    },
    getTabModuleKeys(tabName) {
      switch (tabName) {
        case 'holiday':
          return ['holiday']
        case 'group':
          return ['group']
        case 'restGroup':
          return ['restGroup']
        case 'leave':
          return ['marriageLeaveRule', 'funeralLeaveRule', 'annualLeaveRule', 'maternityLeaveRule']
        case 'deduct':
          return ['lateRule', 'missingCardRule', 'absenteeismRule']
        case 'special':
          return ['exemptUser']
        case 'extraLeave':
          return ['extraLeave']
        default:
          return []
      }
    },
    async loadModulesByTab(tabName, force = false) {
      const moduleKeys = this.getTabModuleKeys(tabName)
      if (!moduleKeys.length) return
      await Promise.all(moduleKeys.map(key => this.loadModule(key, force)))
    },
    async loadModule(moduleType, force = false) {
      const state = this.moduleState[moduleType]
      if (!state) return
      if (!force && state.loaded) return
      state.loading = true
      try {
        if (moduleType === 'restGroup') {
          const res = await getAttendanceRestGroupList({
            keyword: state.query.keyword,
            currentPage: state.query.currentPage,
            pageSize: state.query.pageSize
          })
          const data = res.data || {}
          state.list = data.list || []
          state.pagination = {
            total: data.pagination ? data.pagination.total : 0,
            currentPage: state.query.currentPage,
            pageSize: state.query.pageSize
          }
        } else {
          const res = await getAttendanceConfigList({
            moduleType,
            keyword: state.query.keyword,
            year: state.query.year,
            currentPage: state.query.currentPage,
            pageSize: state.query.pageSize
          })
          const data = res.data || {}
          state.list = data.list || []
          state.pagination = {
            total: data.pagination ? data.pagination.total : 0,
            currentPage: state.query.currentPage,
            pageSize: state.query.pageSize
          }
        }
        state.loaded = true
      } finally {
        state.loading = false
      }
    },
    openRestGroupDialog(row) {
      this.$refs.restGroupDialog && this.$refs.restGroupDialog.open(row)
    },
    onRestGroupSaved() {
      this.moduleState.restGroup.loaded = false
      this.loadModule('restGroup', true)
      this.loadOverview()
    },
    handleTabChange(tab) {
      const tabName = tab && tab.name ? tab.name : this.activeTab
      this.loadModulesByTab(tabName)
    },
    handleModuleSearch(moduleType) {
      const state = this.moduleState[moduleType]
      if (!state) return
      state.query.currentPage = 1
      state.loaded = false
      this.loadModule(moduleType, true)
    },
    handleModuleReset(moduleType) {
      const state = this.moduleState[moduleType]
      if (!state) return
      state.query.keyword = ''
      state.query.currentPage = 1
      if (Object.prototype.hasOwnProperty.call(state.query, 'year')) {
        state.query.year = ['holiday', 'extraLeave'].includes(moduleType) ? CURRENT_YEAR : null
      }
      state.loaded = false
      this.loadModule(moduleType, true)
    },
    openBaseDialog() {
      this.$refs.itemDialog.open({
        moduleType: 'base',
        title: this.baseInfo.id ? '编辑基础扣款设置' : '新增基础扣款设置',
        data: this.baseInfo,
        mode: this.baseInfo.id ? 'edit' : 'create'
      })
    },
    openBaseHistory() {
      if (!this.baseInfo.id) {
        this.$message.warning('当前尚未保存基础扣款设置')
        return
      }
      this.openHistory('base', this.baseInfo, '基础扣款设置')
    },
    openConfigDialog(moduleType, row) {
      this.$refs.itemDialog.open({
        moduleType,
        title: `${row && row.id ? '编辑' : '新增'}${this.getModuleLabel(moduleType)}`,
        data: row ? { ...row } : null,
        mode: row && row.id ? 'edit' : 'create'
      })
    },
    async handleDialogSubmit({ moduleType, data, done }) {
      try {
        if (moduleType === 'base') {
          const payload = {
            id: data.id,
            leaveDeductDailySalaryRate: data.leaveDeductDailySalaryRate,
            sickLeaveDeductDailySalaryRate: data.sickLeaveDeductDailySalaryRate,
            remark: data.remark,
            changeReason: data.changeReason
          }
          await saveAttendanceBaseInfo(payload)
          await Promise.all([this.loadBaseInfo(), this.loadOverview()])
        } else {
          await saveAttendanceConfig({
            moduleType,
            changeReason: data.changeReason,
            data: this.buildModuleSaveData(moduleType, data)
          })
          await Promise.all([this.loadModule(moduleType, true), this.loadOverview()])
        }
        this.$message.success('保存成功')
        done()
      } catch (error) {
        done(false)
      }
    },
    buildModuleSaveData(moduleType, data) {
      const payload = { ...data }
      delete payload.changeReason
      if (moduleType === 'absenteeismRule' && Number(payload.actionType) === 2) {
        payload.deductMode = null
        payload.deductValue = null
      }
      if (moduleType === 'group') {
        payload.monthlyRestDays = 0
        payload.halfDaySplitRestDays = 0
        payload.restUnlockCycle = 0
        payload.lateToleranceMinutes = null
        payload.earlyLeaveToleranceMinutes = null
      }
      return payload
    },
    async handleDelete(moduleType, row) {
      if (!row || !row.id) {
        this.$message.warning('当前记录尚未保存，无法删除')
        return
      }
      if (moduleType === 'restGroup') {
        try {
          await this.$confirm(`确定删除应休分组「${row.groupName || row.id}」吗？如有人员仍绑定将删除失败。`, '删除确认', {
            type: 'warning',
            confirmButtonText: '删除',
            cancelButtonText: '取消'
          })
          await deleteAttendanceRestGroup(row.id)
          this.$message.success('删除成功')
          this.moduleState.restGroup.loaded = false
          await Promise.all([this.loadModule('restGroup', true), this.loadOverview()])
        } catch (error) {
          if (error === 'cancel' || error === 'close') return
        }
        return
      }
      try {
        const { value } = await this.$prompt(`请输入删除【${this.getModuleLabel(moduleType)}】的原因（可选）`, '删除确认', {
          confirmButtonText: '确认删除',
          cancelButtonText: '取消',
          inputPlaceholder: '例如：规则调整后停用',
          inputPattern: /^.{0,200}$/,
          inputErrorMessage: '删除原因不能超过200个字符'
        })
        await deleteAttendanceConfig({
          moduleType,
          id: row.id,
          changeReason: value || ''
        })
        this.$message.success('删除成功')
        await Promise.all([this.loadModule(moduleType, true), this.loadOverview()])
      } catch (error) {
        if (error === 'cancel' || error === 'close') return
      }
    },
    openHistory(moduleType, row, title) {
      if (!row || !row.id) {
        this.$message.warning('请先保存后再查看历史')
        return
      }
      this.$refs.historyDialog.open({
        moduleType,
        bizId: row.id,
        title
      })
    },
    showGroupUsers(row) {
      if (!row || !row.id) {
        this.$message.warning('请先保存分组后再查看成员')
        return
      }
      this.$refs.groupUserDialog.init(row)
    },
    getModuleLabel(moduleType) {
      return {
        base: '基础扣款设置',
        holiday: '公休时间',
        group: '考勤分组',
        restGroup: '应休分组',
        marriageLeaveRule: '婚假规则',
        funeralLeaveRule: '丧假规则',
        annualLeaveRule: '年假规则',
        maternityLeaveRule: '产假规则',
        lateRule: '迟到/早退扣款规则',
        missingCardRule: '忘记打卡规则',
        absenteeismRule: '旷工规则',
        exemptUser: '免考勤人员',
        extraLeave: '额外假期'
      }[moduleType] || '配置'
    },
    getDeductModeText(value) {
      const target = this.deductModeOptions.find(item => Number(item.value) === Number(value))
      return target ? target.label : '无'
    },
    getActionTypeText(value) {
      const target = this.actionTypeOptions.find(item => Number(item.value) === Number(value))
      return target ? target.label : '无'
    },
    buildAbsenteeismDeductText(row) {
      if (Number(row.actionType) === 2) {
        return row.actionText || '视为自离'
      }
      return `${this.getDeductModeText(row.deductMode)} / ${row.deductValue || 0}`
    },
    renderUpperValue(value, suffix) {
      return value === null || value === undefined || value === '' ? '无上限' : `${value}${suffix || ''}`
    },
    buildHolidayTitle(row) {
      return `${row.holidayDate}${row.holidayName ? ` · ${row.holidayName}` : ''}`
    },
    buildYearRangeTitle(row, prefix) {
      return row.maxYears === null || row.maxYears === undefined || row.maxYears === ''
        ? `${prefix} ≥${row.minYears}年`
        : `${prefix} ${row.minYears}-${row.maxYears}年`
    },
    buildMinuteRangeTitle(row, prefix) {
      return row.maxMinutes === null || row.maxMinutes === undefined || row.maxMinutes === ''
        ? `${prefix} ≥${row.minMinutes}分钟`
        : `${prefix} ${row.minMinutes}-${row.maxMinutes}分钟`
    },
    buildCountRangeTitle(row, prefix) {
      return row.maxCount === null || row.maxCount === undefined || row.maxCount === ''
        ? `${prefix} ≥${row.minCount}次`
        : `${prefix} ${row.minCount}-${row.maxCount}次`
    },
    buildDecimalRangeTitle(row, prefix) {
      return row.maxDays === null || row.maxDays === undefined || row.maxDays === ''
        ? `${prefix} ≥${row.minDays}天`
        : `${prefix} ${row.minDays}-${row.maxDays}天`
    },
    buildExtraLeaveTitle(row) {
      return `${row.userName} · ${row.grantYear}年 · ${row.leaveName}`
    }
  }
}
</script>

<style lang="scss" scoped>
.attendance-setting-page {
  height: calc(100vh - 72px);
  overflow: hidden;
  background: #f5f7fb;

  .NCC-common-layout-center,
  .NCC-common-layout-main {
    height: 100%;
    min-height: 0;
  }
}

/* 左右分栏；勿在此节点叠加 NCC-flex-main（global 为 flex-direction:column 会压成上下布局） */
.page-shell {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 14px;
  height: 100%;
  min-height: 0;
  overflow: hidden;
}

.page-side {
  box-sizing: border-box;
  flex: 0 0 380px;
  width: 380px;
  max-width: 380px;
  min-width: 280px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
  /* 防止侧栏内容溢出到右侧主区域，造成与 Tab 栏叠层错乱 */
  overflow-x: hidden;
  overflow-y: auto;
}

.page-main {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  background: #fff;
}

.summary-panel,
.summary-card,
.page-main__toolbar,
.section-card {
  border: 1px solid #e8edf5;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.05);
}

.summary-panel {
  padding: 18px 18px 16px;
}

.summary-panel__eyebrow {
  margin-bottom: 8px;
  color: #409eff;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.summary-panel__title {
  margin: 0;
  color: #1f2d3d;
  font-size: 24px;
  font-weight: 700;
}

.summary-panel__desc {
  margin: 8px 0 0;
  color: #606266;
  font-size: 13px;
  line-height: 1.75;
  word-break: break-word;
  overflow-wrap: break-word;
}

/* 单列铺满侧栏宽度，避免 2×2 窄格内说明文字溢出 */
.summary-metrics {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
  margin-top: 14px;
}

.summary-metric {
  box-sizing: border-box;
  display: flex;
  min-height: 100px;
  height: auto;
  flex-direction: column;
  justify-content: center;
  padding: 12px;
  border-radius: 12px;
  background: linear-gradient(135deg, #f8fbff 0%, #eef6ff 100%);
  border: 1px solid #edf3fb;
  overflow: hidden;
}

.summary-metric__label {
  flex-shrink: 0;
  color: #606266;
  font-size: 12px;
}

.summary-metric__value {
  flex-shrink: 0;
  margin-top: 6px;
  color: #1f2d3d;
  font-size: 24px;
  font-weight: 700;
  line-height: 1;
}

.summary-metric__hint {
  flex-shrink: 0;
  margin-top: 8px;
  color: #909399;
  font-size: 11px;
  line-height: 1.55;
  word-break: break-word;
  overflow-wrap: break-word;
}

.summary-card {
  padding: 16px 18px;
}

.summary-card__title {
  color: #1f2d3d;
  font-size: 15px;
  font-weight: 600;
}

.summary-detail {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 14px;
}

.summary-detail__item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.summary-detail__label {
  flex-shrink: 0;
  max-width: 42%;
  color: #909399;
  font-size: 12px;
  line-height: 1.5;
}

.summary-detail__value {
  min-width: 0;
  flex: 1;
  color: #303133;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.5;
  text-align: right;
  word-break: break-word;
  overflow-wrap: break-word;
}

.page-main__toolbar {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: #fff;
  position: relative;
  z-index: 2;
}

.page-main__title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}

.page-main__title-icon {
  flex-shrink: 0;
  color: #409eff;
  font-size: 16px;
}

.page-main__title-text {
  color: #909399;
  font-size: 13px;
  font-weight: 500;
}

.page-main__tab-tag {
  margin-left: 2px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.page-main__actions {
  display: flex;
  gap: 10px;
}

.page-main__content {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  margin-top: 12px;
  padding: 0 2px 2px 0;
  overflow: hidden;
}

/* 与 common.scss 中 .NCC-el_tabs 配合：顶栏 Tabs + 下方内容区 flex 占满，避免内容顶到导航上 */
.setting-tabs {
  height: 100%;
  min-height: 0;
}

::v-deep .setting-tabs.el-tabs--top {
  display: flex;
  flex-direction: column;
}

::v-deep .setting-tabs>.el-tabs__header {
  flex-shrink: 0;
  margin: 0 0 12px;
  background: #fff;
  position: relative;
  z-index: 2;
}

::v-deep .setting-tabs .el-tabs__nav-wrap::after {
  height: 1px;
  background-color: #e4e7ed;
}

::v-deep .setting-tabs .el-tabs__item {
  height: 42px;
  padding: 0 18px;
  font-size: 13px;
  line-height: 42px;
}

::v-deep .setting-tabs .el-tabs__item.is-active {
  color: #409eff;
  font-weight: 600;
}

::v-deep .setting-tabs .el-tabs__active-bar {
  height: 3px;
  border-radius: 3px 3px 0 0;
  background-color: #409eff;
}

::v-deep .setting-tabs>.el-tabs__content {
  flex: 1;
  min-height: 0;
  overflow: auto !important;
  overflow-x: hidden;
  position: relative;
  z-index: 1;
}

::v-deep .setting-tabs .el-tab-pane {
  height: 100%;
}

.tab-panel {
  height: 100%;
  overflow: auto;
  padding-right: 2px;
}

.tab-panel--grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  align-content: start;
}

.section-card {
  display: flex;
  flex-direction: column;
}

.section-card--full {
  grid-column: 1 / -1;
}

.section-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.section-card__title {
  color: #1f2d3d;
  font-size: 15px;
  font-weight: 600;
}

.section-card__desc {
  margin-top: 4px;
  color: #909399;
  font-size: 12px;
  line-height: 1.6;
}

.section-card__actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

.section-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.section-filter__year {
  flex: 0 0 110px;
  width: 110px;
}

.section-filter__keyword {
  flex: 1 1 200px;
  min-width: 160px;
  max-width: 100%;
}

.section-empty {
  padding-top: 12px;
}

.base-card__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.base-card__item {
  box-sizing: border-box;
  display: flex;
  min-height: 100px;
  flex-direction: column;
  justify-content: center;
  padding: 12px;
  border-radius: 12px;
  background: #f8fbff;
  border: 1px solid #edf3fb;
}

.base-card__item--wide {
  grid-column: 1 / -1;
  min-height: 0;
  justify-content: flex-start;
}

.base-card__label {
  color: #909399;
  font-size: 12px;
}

.base-card__value {
  margin-top: 8px;
  color: #1f2d3d;
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
}

.base-card__hint,
.base-card__remark {
  margin-top: 10px;
  color: #606266;
  font-size: 13px;
  line-height: 1.7;
}

.danger-text {
  color: #f56c6c;
}

.cell-with-icon {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  vertical-align: middle;
  white-space: nowrap;
}

.cell-with-icon>i {
  flex-shrink: 0;
  margin-right: 6px;
  font-size: 14px;
}

.cell-with-icon>span:last-child {
  overflow: hidden;
  text-overflow: ellipsis;
}

.cell-with-icon--primary>i {
  color: #409eff;
}

.cell-with-icon--success>i {
  color: #67c23a;
}

.cell-with-icon--danger>i {
  color: #f56c6c;
}

@media screen and (max-width: 1400px) {
  .tab-panel--grid {
    grid-template-columns: 1fr;
  }
}

::v-deep .section-card .el-card__header {
  padding: 14px 16px 10px;
}

::v-deep .section-card .el-card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  padding: 0 16px 16px;
}
</style>
