<!-- 门禁报警记录 - 公共组件 -->
<template>
    <div class="UserManage">
        <!-- 全局头部栏 -->
        <GlobalHeader :on-search="handleSearch" />
        <DataTable :value="tableAccessAlarmData" :loading="loading" v-model:selection="selectedRows" dataKey="id"
            @sort="onSort" @row-click="handleRowClick" paginator :rows="queryData.size" :totalRecords="totalItems"
            @page="onPage" :lazy="true" :rowsPerPageOptions="[5, 10, 20, 50]" class="table" scrollable
            :sortField="sortField" :sortOrder="sortOrder"
            paginatorTemplate="PrevPageLink PageLinks NextPageLink RowsPerPageDropdown"
            :pageLinkSize="10">
            <template #paginatorprevpagelinkicon>
                <span class="paginator-btn-text"><i class="pi pi-chevron-left"></i> {{ $t('common.prevPage') }}</span>
            </template>
            <template #paginatornextpagelinkicon>
                <span class="paginator-btn-text">{{ $t('common.nextPage') }} <i class="pi pi-chevron-right"></i></span>
            </template>
            <template #header>
                <div class="table-actions">
                    <div class="table-left-wrapper">
                        <div class="select-all-wrapper">
                            <Checkbox :inputId="'selectAll'" v-model="isAllSelected" :binary="true" />
                            <label :for="'selectAll'" class="select-all-label">
                                {{ $t('common.selectAll', { count: selectedRows.length }) }}
                            </label>
                        </div>
                        <div class="table-left" @click="handleBatchDelete">
                            <!-- <Button label="批量删除" icon="pi pi-trash" class="p-button-danger" @click="handleBatchDelete"
                                :disabled="!selectedRows || selectedRows.length === 0
                                    " /> -->
                            <div class="delIcon">
                                <img src="../../images/login/del.png" alt="">
                            </div>
                            <div class="delItems">{{ $t('common.batchDelete') }}</div>
                        </div>
                    </div>
                    <div class="table-right">
                        <ImportExportButton export-only @export="handleExport" />
                    </div>
                </div>
            </template>
            <Column selectionMode="multiple" headerStyle="width: 3rem; white-space: nowrap;"></Column>
            <Column v-if="columnVisible('al_asset_number')" field="al_asset_number" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('assetList.assetNumber') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('al_asset_number')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('al_asset_number', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('al_asset_number', $t('assetList.assetNumber'), $event)"></i>

                        </div>
                    </div>
                </template>
            </Column>
            <Column v-if="columnVisible('al_asset_name')" field="al_asset_name" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('assetList.assetName') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('al_asset_name')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('al_asset_name', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('al_asset_name', $t('assetList.assetName'), $event)"></i>

                        </div>
                    </div>
                </template>

            </Column>

            <Column v-if="columnVisible('al_asset_pic')" field="al_asset_pic" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('assetList.responsiblePerson') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('al_asset_pic')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('al_asset_pic', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('al_asset_pic', $t('assetList.responsiblePerson'), $event)"></i>
                        </div>
                    </div>
                </template>
            </Column>
            <Column v-if="columnVisible('al_asset_department')" field="al_asset_department" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('assetList.assetDepartment') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('al_asset_department')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('al_asset_department', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('al_asset_department', $t('assetList.assetDepartment'), $event)"></i>
                        </div>
                    </div>
                </template>
            </Column>
            <Column v-if="columnVisible('al_factory_area_name')" field="al_factory_area_name" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('alarmRecord.belongFactoryArea') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('al_factory_area_name')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('al_factory_area_name', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('al_factory_area_name', $t('alarmRecord.belongFactoryArea'), $event)"></i>
                        </div>
                    </div>
                </template>
            </Column>
            <Column v-if="columnVisible('im_factory_area_name')" field="im_factory_area_name" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('alarmRecord.currentFactoryArea') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('im_factory_area_name')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('im_factory_area_name', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('im_factory_area_name', $t('alarmRecord.currentFactoryArea'), $event)"></i>

                        </div>
                    </div>
                </template>
            </Column>

            <Column v-if="columnVisible('alarm_time')" field="alarm_time" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('alarmRecord.alarmTime') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('alarm_time')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('alarm_time', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('alarm_time', $t('alarmRecord.alarmTime'), $event)"></i>
                        </div>
                    </div>
                </template>
                <template #body="{ data }">
                    {{ formatDateTime(data.alarm_time) }}
                </template>
            </Column>
            <Column v-if="columnVisible('im_name')" field="im_name" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('alarmRecord.infoMachineName') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('im_name')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('im_name', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('im_name', $t('alarmRecord.infoMachineName'), $event)"></i>
                        </div>
                    </div>
                </template>
            </Column>
            <Column v-if="columnVisible('signal_machine')" field="al_asset_name" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('alarmRecord.signalMachine') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('al_asset_name')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('al_asset_name', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('al_asset_name', $t('alarmRecord.signalMachine'), $event)"></i>

                        </div>
                    </div>
                </template>
            </Column>


             <Column v-if="columnVisible('epc')" field="epc" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>EPC</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('epc')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('epc', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('epc', 'EPC', $event)"></i>
                        </div>
                    </div>
                </template>
            </Column>
            <Column v-if="columnVisible('im_information_machine_type')" field="im_information_machine_type" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('alarmRecord.alarmType') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('im_information_machine_type')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('im_information_machine_type', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('im_information_machine_type', $t('alarmRecord.alarmType'), $event)"></i>
                        </div>
                    </div>
                </template>
            </Column>
            <Column v-if="columnVisible('al_type_specification')" field="al_type_specification" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('assetList.typeSpecification') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('al_type_specification')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('al_type_specification', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('al_type_specification', $t('assetList.typeSpecification'), $event)"></i>

                        </div>
                    </div>
                </template>
            </Column>
            <Column v-if="columnVisible('create_at')" field="create_at" headerStyle="white-space: nowrap;">
                <template #header>
                    <div class="column-header-with-search">
                        <span>{{ $t('common.createTime') }}</span>
                        <div class="header-icons">
                            <img :src="getSortIcon('create_at')" class="sort-icon" alt=""
                                @click.stop="handleSortIconClick('create_at', $event)" />
                            <i class="pi pi-search search-icon"
                                @click.stop="openSearchPopup('create_at', $t('common.createTime'), $event)"></i>
                        </div>
                    </div>
                </template>
                <template #body="{ data }">
                    {{ formatDateTime(data.create_at) }}
                </template>
            </Column>
            <template #paginatorstart>
                <span class="select-all-label-paginator">{{ $t('common.selectedTotal', { selected: selectedRows.length, total: totalItems }) }}</span>
            </template>
        </DataTable>
        <!-- 删除确认弹窗 -->
        <!-- <Dialog v-model:visible="deleteDialogVisible" header="确认删除" modal :style="{ width: '300px' }">
            <p>
                {{
                    deleteDialogType === "batch"
                        ? `确定要删除选中的 ${selectedRows.length} 条数据吗？`
                        : "确定要删除这条数据吗？"
                }}
            </p>
            <template #footer>
                <Button label="取消" icon="pi pi-times" @click="deleteDialogVisible = false" class="p-button-text" />
                <Button label="确定" icon="pi pi-check" :loading="loading" @click="confirmDelete" class="p-button-danger"
                    autofocus />
            </template>
        </Dialog> -->
        <!-- 删除确认弹窗（原生 div）好改样式 -->
        <div v-show="deleteDialogVisible" class="delete-dialog-overlay" @click.self="deleteDialogVisible = false">
            <div class="del_box" @click.stop>
                <div class="header">
                    <div class="left">
                        <div class="img_box">
                            <img src="../../images/login/confirm.png" alt="">
                        </div>
                        <div class="del_name">{{ $t('common.confirmDelete') }}</div>
                    </div>
                    <div class="del_icon" @click="deleteDialogVisible = false">
                        <img src="../../images/login/delClose.png" alt="">
                    </div>
                </div>
                <div class="delText">
                    {{
                        deleteDialogType === "batch"
                            ? $t('common.deleteBatchConfirm', { count: selectedRows.length })
                            : $t('common.deleteSingleConfirm')
                    }}
                </div>
                <div class="del-btn">
                    <div class="btnAncle" @click="deleteDialogVisible = false">{{ $t('common.cancel') }}</div>
                    <div class="btnOk" :class="{ 'btnOk--loading': loading }"
                        :style="{ pointerEvents: loading ? 'none' : 'auto' }" @click="confirmDelete">{{ $t('common.confirm') }}</div>
                </div>
            </div>
        </div>
        <!-- 列搜索弹窗 -->
        <div v-if="searchPopupVisible" class="column-search-popup" :style="searchPopupStyle" @click.stop>
            <!-- 日期范围选择器（用于创建时间列） -->
            <Calendar v-if="currentSearchColumn === 'create_at'" v-model="currentDateRange" selectionMode="range"
                :placeholder="$t('common.selectTimeRange', { label: currentSearchLabel })" class="search-popup-input" dateFormat="yy-mm-dd" showIcon
                :manualInput="false" showTime showSeconds hourFormat="24"  panelClass="datepicker-panel-scale-07"  />
            <!-- 文本输入框（用于其他列） -->
            <InputText v-else v-model="currentSearchValue" :placeholder="$t('common.searchColumnPlaceholder', { label: currentSearchLabel })"
                class="search-popup-input" @keyup.enter="handleColumnSearch" />
            <div class="search-popup-buttons">
                <div class="search_reset" @click="handleColumnReset">{{ $t('common.reset') }}</div>
                <div class="search-btn" @click="handleColumnSearch">{{ $t('common.searchBtn') }}</div>
            </div>
        </div>
        <!-- 遮罩层，用于点击外部关闭弹窗 -->
        <div v-if="searchPopupVisible" class="search-popup-overlay" @click="closeSearchPopup"></div>

        <!-- 失败/错误提示（与资产台账一致：右上角原生样式） -->
        <div v-if="showFailToast" class="edit-fail-toast">
            <div class="totast_wrapper">
                <div class="left_box">
                    <div class="edit-fail-toast-icon">
                        <img src="../../images/commen/fail.png" alt="失败" />
                    </div>
                    <div class="edit-fail-toast-title">{{ failToastContent.title }}</div>
                </div>
                <div class="edit-fail-toast-close" @click="closeFailToast">
                    <img src="../../images/commen/close.png" alt="关闭" />
                </div>
            </div>
            <div class="edit-fail-toast-content">
                <div class="edit-fail-toast-detail">{{ failToastContent.detail }}</div>
            </div>
        </div>
        <!-- 成功提示（与失败提示统一：右上角、左对齐布局） -->
        <div v-if="showSuccessToast" class="edit-success-toast">
            <div class="totast_wrapper">
                <div class="left_box">
                    <div class="edit-success-toast-icon">
                        <img src="../../images/commen/success.png" alt="成功" />
                    </div>
                    <div class="edit-success-toast-title">{{ successToastContent.title }}</div>
                </div>
                <div class="edit-success-toast-close" @click="closeSuccessToast">
                    <img src="../../images/commen/close.png" alt="关闭" />
                </div>
            </div>
            <div class="edit-success-toast-content">
                <div class="edit-success-toast-detail">{{ successToastContent.detail }}</div>
            </div>
        </div>
    </div>
</template>
<script setup>
import {
    getTablist,
    delTablist,
    exportAccess,
} from "../../api/asset/accessalarm";
import ImportExportButton from "../ImportExportButton.vue";
import { ref, reactive, onMounted, computed } from "vue";
import { useI18n } from "vue-i18n";
import { useSystemStore } from "../../store/system";
import GlobalHeader from "../GlobalHeader.vue";
import DataTable from "primevue/datatable";
import Column from "primevue/column";
import Button from "primevue/button";
import InputText from "primevue/inputtext";
import Dialog from "primevue/dialog";
import Calendar from "primevue/calendar";
import Checkbox from "primevue/checkbox";
import topIcon from "../../images/login/top.png";
import bottomIcon from "../../images/login/bottom.png";
import noneIcon from "../../images/login/none.png";


const systemStore = useSystemStore();
const { t } = useI18n();

// 表头列 field 与字段权限 key（与 fieldPermissionGroups AssetAlarmRecord 一致）的映射，用于按 advanced_permissions 控制列显示
const ASSET_ALARM_RECORD_COLUMN_PERMISSION_KEY = {
    al_asset_number: "asset_no_assetAlarmRecord",
    al_asset_name: "asset_name_assetAlarmRecord",
    al_asset_pic: "responsible_assetAlarmRecord",
    al_asset_department: "asset_dept_assetAlarmRecord",
    al_factory_area_name: "factory_area_assetAlarmRecord",
    im_factory_area_name: "current_factory_assetAlarmRecord",
    alarm_time: "alarm_time_assetAlarmRecord",
    im_name: "info_machine_name_assetAlarmRecord",
    signal_machine: "signal_machine_assetAlarmRecord", // 信号机列（与资产名称同 field，用逻辑 key 区分）
    epc: "epc_assetAlarmRecord",
    im_information_machine_type: "alarm_type_assetAlarmRecord",
    al_type_specification: "spec_model_assetAlarmRecord",
};

const ASSET_ALARM_RECORD_PERMISSION_KEYS = new Set(Object.values(ASSET_ALARM_RECORD_COLUMN_PERMISSION_KEY));

/** 当前用户是否有某列的字段权限。为空或与本模块无交集时显示全部列；有本模块权限时才按权限过滤列 */
const columnVisible = (field) => {
    const codes = systemStore.advancedPermissionCodes;
    if (!codes || codes.length === 0) return true;
    const hasAnyAlarmRecord = codes.some((k) => ASSET_ALARM_RECORD_PERMISSION_KEYS.has(k));
    if (!hasAnyAlarmRecord) return true;
    const permissionKey = ASSET_ALARM_RECORD_COLUMN_PERMISSION_KEY[field];
    if (!permissionKey) return true;
    return codes.includes(permissionKey);
};

// 原生提示（与资产台账一致）
const showFailToast = ref(false);
const failToastContent = reactive({ title: "", detail: "" });
let failToastTimer = null;
const showSuccessToast = ref(false);
const successToastContent = reactive({ title: "", detail: "" });
let successToastTimer = null;
const FAIL_TOAST_AUTO_CLOSE_MS = 3000;
const showFailToastMsg = (title, detail) => {
    failToastContent.title = title || t("alarmRecord.error");
    failToastContent.detail = detail || "";
    showFailToast.value = true;
    if (failToastTimer) clearTimeout(failToastTimer);
    failToastTimer = setTimeout(() => { showFailToast.value = false; }, FAIL_TOAST_AUTO_CLOSE_MS);
};
const showSuccessToastMsg = (title, detail) => {
    successToastContent.title = title || t("common.success");
    successToastContent.detail = detail || "";
    showSuccessToast.value = true;
    if (successToastTimer) clearTimeout(successToastTimer);
    successToastTimer = setTimeout(() => { showSuccessToast.value = false; }, FAIL_TOAST_AUTO_CLOSE_MS);
};
const closeFailToast = () => {
    showFailToast.value = false;
    if (failToastTimer) clearTimeout(failToastTimer);
    failToastTimer = null;
};
const closeSuccessToast = () => {
    showSuccessToast.value = false;
    if (successToastTimer) clearTimeout(successToastTimer);
    successToastTimer = null;
};
const queryData = ref({
    page: 1,
    size: 10,
});

// 状态管理
const loading = ref(false);
const tableAccessAlarmData = ref([]);
const totalItems = ref(0);
const dialogVisible = ref(false);
const deleteDialogVisible = ref(false);
const isReadonly = ref(false); // 新增：控制表单是否只读
const dialogType = ref("add"); // add, edit, info
const deleteDialogType = ref("single");
const currentId = ref(null);
const selectedRows = ref([]); // 存储选中的行



const formInline = reactive({
    user: "",
    sort: {
        column: "create_at",
        num: "desc",
    },
});
// 门禁报警记录表单数据
const formUserManageData = reactive({
    comment: "",
    name: "",
    password: "",
    checked_password: "",
    employee_id: null,
    roles: [],
});
// 员工列表和角色列表从 store 获取
const employeeOptions = computed(() => systemStore.employeeOptions);
const roleOptions = computed(() => systemStore.roleOptions);

// 计算角色显示文本（当选择的角色超过2个时显示）
const selectedRolesLabel = computed(() => {
    if (!formUserManageData.roles || formUserManageData.roles.length === 0) {
        return "";
    }
    const count = formUserManageData.roles.length;
    return `已选择${count}个角色`;
});

// 计算&nbsp;&nbsp;描述信息字符数
const commentCharCount = computed(() => {
    return formUserManageData.comment ? formUserManageData.comment.length : 0;
});
const maxCommentLength = 500;

// 全选状态
const isAllSelected = computed({
    get: () => {
        return selectedRows.value.length > 0 && selectedRows.value.length === tableAccessAlarmData.value.length;
    },
    set: (value) => {
        if (value) {
            selectedRows.value = [...tableAccessAlarmData.value];
        } else {
            selectedRows.value = [];
        }
    }
});

// 列搜索相关状态
const searchPopupVisible = ref(false);
const currentSearchColumn = ref('');
const currentSearchLabel = ref('');
const currentSearchValue = ref('');
const currentDateRange = ref(null); // 日期范围选择器的值
const searchPopupStyle = ref({});
const columnFilters = ref({}); // 存储每列的筛选值 { column: value }


const formatDateTime = (timestamp) => {
    if (!timestamp && timestamp !== 0) return "-";

    try {
        // 处理时间戳（可能是数字或字符串）
        let date;
        if (typeof timestamp === 'number' || (typeof timestamp === 'string' && /^\d+$/.test(timestamp))) {
            // 如果是时间戳，转换为毫秒（如果小于13位，认为是秒级时间戳）
            const ts = Number(timestamp);
            if (ts === 0) return "-";
            date = new Date(ts < 10000000000 ? ts * 1000 : ts);
        } else {
            // 如果是ISO字符串或其他格式
            date = new Date(timestamp);
        }

        if (isNaN(date.getTime())) return "-";

        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, "0");
        const day = String(date.getDate()).padStart(2, "0");
        const hours = String(date.getHours()).padStart(2, "0");
        const minutes = String(date.getMinutes()).padStart(2, "0");
        const seconds = String(date.getSeconds()).padStart(2, "0");

        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    } catch (error) {
        console.error("日期格式化错误:", error);
        return "-";
    }
};


// 计算排序字段（用于 DataTable 的 sortField 属性）
const sortField = computed(() => formInline.sort.column || "create_at");

// 计算排序顺序（用于 DataTable 的 sortOrder 属性，1=升序，-1=降序）
const sortOrder = computed(() => formInline.sort.num === "asc" ? 1 : -1);

// 表头排序图标：未排序 none，升序 top，降序 bottom（对应 images/login）
const getSortIcon = (field) => {
    if (sortField.value !== field) return noneIcon;
    return sortOrder.value === 1 ? topIcon : bottomIcon;
};

// 处理排序图标点击
const handleSortIconClick = (field, event) => {
    event.stopPropagation(); // 阻止事件冒泡
    if (formInline.sort.column === field) {
        // 如果当前列已排序，切换升序/降序
        formInline.sort.num = formInline.sort.num === "asc" ? "desc" : "asc";
    } else {
        // 如果点击的是其他列，设置为该列升序
        formInline.sort.column = field;
        formInline.sort.num = "asc";
    }
    fetchUserManageDataList();
};

// 获取门禁报警记录数据
const fetchUserManageDataList = async () => {
    // 构建filter对象，包含所有表头字段
    const filter = {
        al_asset_number: columnFilters.value.al_asset_number || "",
        im_number: columnFilters.value.im_number || "",
        al_asset_name: columnFilters.value.al_asset_name || "",
        al_asset_pic: columnFilters.value.al_asset_pic || "",
        al_factory_area_name: columnFilters.value.al_factory_area_name || "",
        al_asset_department: columnFilters.value.al_asset_department || "",
        im_name: columnFilters.value.im_name || "",
        al_type_specification: columnFilters.value.al_type_specification || "",
    };

    // 处理日期范围筛选，使用 create_at 作为字段名
    if (columnFilters.value.create_at) {
        filter.create_at = {
            start_time: columnFilters.value.create_at.start_time || "",
            end_time: columnFilters.value.create_at.end_time || ""
        };
    } else {
        filter.create_at = {
            start_time: "",
            end_time: ""
        };
    }

    const params = {
        page: {
            page_num: queryData.value.page,
            page_size: queryData.value.size,
        },
        search: formInline.user || "",
        sort: [{
            column: formInline.sort.column,
            order: formInline.sort.num,
        }],
        filter: filter,
    };

    // loading.value = true;
    try {
        const res = await getTablist(params);
        tableAccessAlarmData.value = res.data || [];
        totalItems.value = res.total || 0;
    } catch (error) {
        // 从错误对象中提取 msg 字段，优先顺序：response.data.msg > response.data.message > data.msg > data.message > message
        let errorMsg = t("alarmRecord.getDataFail");
        if (error?.response?.data?.msg) {
            errorMsg = `${t("alarmRecord.accessAlarmListErrorPrefix")}${error.response.data.msg}`;
        } else if (error?.response?.data?.message) {
            errorMsg = `${t("alarmRecord.accessAlarmListErrorPrefix")}${error.response.data.message}`;
        } else if (error?.data?.msg) {
            errorMsg = `${t("alarmRecord.accessAlarmListErrorPrefix")}${error.data.msg}`;
        } else if (error?.data?.message) {
            errorMsg = `${t("alarmRecord.accessAlarmListErrorPrefix")}${error.data.message}`;
        } else if (error?.message && error.message !== "Error") {
            errorMsg = `${t("alarmRecord.accessAlarmListErrorPrefix")}${error.message}`;
        }
        showFailToastMsg(t("alarmRecord.error"), errorMsg);
        console.error(error);
    } finally {
        setTimeout(() => {
            loading.value = false;
        }, 500);
    }
};

// 处理搜索
const handleSearch = (searchText) => {
    formInline.user = searchText || "";
    selectedRows.value = [];
    fetchUserManageDataList();
};

const onPage = (event) => {
    queryData.value.page = event.page + 1;
    queryData.value.size = event.rows;
    fetchUserManageDataList();
};

// 导出门禁报警记录
const handleExport = async () => {
    const filter = {
        al_asset_number: columnFilters.value.al_asset_number || "",
        im_number: columnFilters.value.im_number || "",
        al_asset_name: columnFilters.value.al_asset_name || "",
        al_asset_pic: columnFilters.value.al_asset_pic || "",
        al_factory_area_name: columnFilters.value.al_factory_area_name || "",
        al_asset_department: columnFilters.value.al_asset_department || "",
        im_name: columnFilters.value.im_name || "",
        al_type_specification: columnFilters.value.al_type_specification || "",
    };
    if (columnFilters.value.create_at) {
        filter.create_at = {
            start_time: columnFilters.value.create_at.start_time || "",
            end_time: columnFilters.value.create_at.end_time || "",
        };
    } else {
        filter.create_at = { start_time: "", end_time: "" };
    }
    const payload = { search: formInline.user || "", filter };
    if (selectedRows.value.length > 0) {
        payload.ids = selectedRows.value.map((r) => r.id);
    }
    try {
        const res = await exportAccess(payload);
        const blob = res?.data instanceof Blob ? res.data : res;
        if (!blob) throw new Error(t("alarmRecord.exportFail"));
        const url = URL.createObjectURL(blob);
        const link = document.createElement("a");
        link.href = url;
        link.download = `${t("alarmRecord.accessAlarmExportFileName")}_${Date.now()}.xlsx`;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(url);
        showSuccessToastMsg(t("common.success"), t("alarmRecord.exportSuccess"));
    } catch (err) {
        const msg = err?.response?.data?.msg ?? err?.data?.msg ?? err?.message ?? t("alarmRecord.exportFail");
        showFailToastMsg(t("common.operationFail"), msg);
    }
};

// 新增
const handleAdd = () => {
    dialogType.value = "add";
    currentId.value = null;
    isReadonly.value = false;
    formUserManageData.name = "";
    formUserManageData.comment = "";
    formUserManageData.password = "";
    formUserManageData.checked_password = "";
    formUserManageData.employee_id = null;
    formUserManageData.roles = [];
    dialogVisible.value = true;
};

// 行点击事件
const handleRowClick = (event) => {
    // 如果点击的是复选框区域，不触发编辑
    if (event.originalEvent && event.originalEvent.target.closest('.p-checkbox')) {
        return;
    }
    handleEdit(event.data);
};

// 编辑
const handleEdit = (row) => {
    dialogType.value = "edit";
    currentId.value = row.id;
    isReadonly.value = false;
    formUserManageData.name = row.name || "";
    formUserManageData.comment = row.comment || "";
    formUserManageData.password = row.password || "";
    formUserManageData.checked_password = row.password || "";

    // 根据 al_asset_name 找到对应的 employee_id
    if (row.al_asset_name) {
        const employee = employeeOptions.value.find(emp => emp.name === row.al_asset_name);
        formUserManageData.employee_id = employee ? Number(employee.id) : null;
    } else {
        // 如果API返回了employee_id，直接使用
        formUserManageData.employee_id = row.employee_id ? Number(row.employee_id) : null;
    }

    // 根据 im_factory_area_name 找到对应的角色ID数组
    if (row.im_factory_area_name) {
        // im_factory_area_name 可能是逗号分隔的字符串，如 "机器工程师,plc工程师"
        const roleNames = row.im_factory_area_name.split(',').map(name => name.trim());
        const roleIds = roleNames
            .map(roleName => {
                const role = roleOptions.value.find(r => r.name === roleName);
                return role ? Number(role.id) : null;
            })
            .filter(id => id !== null);
        formUserManageData.roles = roleIds;
    } else if (row.roles) {
        // 如果API返回了roles字段，使用它
        if (Array.isArray(row.roles)) {
            formUserManageData.roles = row.roles.map(id => Number(id));
        } else if (row.roles !== null && row.roles !== undefined && row.roles !== '') {
            formUserManageData.roles = [Number(row.roles)];
        } else {
            formUserManageData.roles = [];
        }
    } else {
        formUserManageData.roles = [];
    }

    dialogVisible.value = true;
};
// 批量删除
const handleBatchDelete = () => {
    if (selectedRows.value.length === 0) return;
    deleteDialogType.value = "batch";
    deleteDialogVisible.value = true;
};

// 删除确定
const confirmDelete = async () => {
    loading.value = true;
    try {
        const ids =
            deleteDialogType.value === "single"
                ? [currentId.value]
                : selectedRows.value.map((r) => r.id);

        console.log(ids);
        await delTablist({ ids });

        showSuccessToastMsg(t("common.success"), deleteDialogType.value === "single" ? t("common.deleteSuccess") : t("common.deleteBatchSuccessDetail", { count: ids.length }));
        fetchUserManageDataList();
        deleteDialogVisible.value = false;
        selectedRows.value = [];
    } catch (e) {
        // 尝试从错误响应中提取消息
        let errorMessage = t("common.deleteFail");
        // 优先从多个位置获取错误消息
        if (e.data?.msg) {
            // 从错误对象附加的 data 中获取
            errorMessage = e.data.msg;
        } else if (e.response?.data?.msg) {
            // 从 response.data.msg 获取（后端返回的错误消息）
            errorMessage = e.response.data.msg;
        } else if (e.data?.message) {
            errorMessage = e.data.message;
        } else if (e.response?.data?.message) {
            errorMessage = e.response.data.message;
        } else if (e.message && e.message !== "Error") {
            // 如果响应拦截器已经将错误消息设置到 message 中，使用它
            errorMessage = e.message;
        }
        showFailToastMsg("错误", errorMessage);
    } finally {
        loading.value = false;
    }
};

const onSort = (event) => {
    formInline.sort.column = event.sortField;
    formInline.sort.num = event.sortOrder === 1 ? "asc" : "desc";
    fetchUserManageDataList();
};

// 打开列搜索弹窗
const openSearchPopup = (column, label, event) => {
    currentSearchColumn.value = column;
    currentSearchLabel.value = label;

    // 如果是日期列，初始化日期范围
    if (column === 'create_at') {
        const filterValue = columnFilters.value[column];
        if (filterValue && filterValue.start_time && filterValue.end_time) {
            currentDateRange.value = [
                new Date(filterValue.start_time),
                new Date(filterValue.end_time)
            ];
        } else {
            currentDateRange.value = null;
        }
        currentSearchValue.value = '';
    } else {
        currentSearchValue.value = columnFilters.value[column] || '';
        currentDateRange.value = null;
    }

    // 计算弹窗位置，使其在对应表头下方居中
    if (event && event.target) {
        // 找到表头单元格元素
        let headerCell = event.target.closest('th');

        // 如果没找到，尝试从图标向上查找
        if (!headerCell) {
            let parent = event.target.parentElement;
            while (parent && parent.tagName !== 'TH') {
                parent = parent.parentElement;
            }
            headerCell = parent;
        }

        if (headerCell) {
            const rect = headerCell.getBoundingClientRect();
            // 如果是日期列，使用更宽的弹窗（包含时间选择器需要更多空间）
            const popupWidth = column === 'create_at' ? 450 : 320;
            const centerX = rect.left + rect.width / 2;
            const leftPosition = centerX - popupWidth / 2;

            // 确保弹窗不超出屏幕左右边界
            const minLeft = 10;
            const maxLeft = window.innerWidth - popupWidth - 10;
            const finalLeft = Math.max(minLeft, Math.min(leftPosition, maxLeft));

            searchPopupStyle.value = {
                position: 'fixed',
                top: `${rect.bottom + 8}px`,
                left: `${finalLeft}px`,
                zIndex: 1000,
                width: `${popupWidth}px`
            };
        } else {
            // 如果找不到表头单元格，使用图标位置
            const rect = event.target.getBoundingClientRect();
            const popupWidth = column === 'create_at' ? 450 : 320;
            const centerX = rect.left + rect.width / 2;
            const leftPosition = centerX - popupWidth / 2;
            const minLeft = 10;
            const maxLeft = window.innerWidth - popupWidth - 10;
            const finalLeft = Math.max(minLeft, Math.min(leftPosition, maxLeft));

            searchPopupStyle.value = {
                position: 'fixed',
                top: `${rect.bottom + 8}px`,
                left: `${finalLeft}px`,
                zIndex: 1000,
                width: `${popupWidth}px`
            };
        }
    } else {
        // 如果没有事件对象，使用默认位置（屏幕中央）
        searchPopupStyle.value = {
            position: 'fixed',
            top: '50%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            zIndex: 1000
        };
    }

    searchPopupVisible.value = true;
};

// 关闭列搜索弹窗
const closeSearchPopup = () => {
    searchPopupVisible.value = false;
    currentSearchColumn.value = '';
    currentSearchLabel.value = '';
    currentSearchValue.value = '';
    currentDateRange.value = null;
};

// 执行列搜索
const handleColumnSearch = () => {
    if (currentSearchColumn.value) {
        // 如果是日期列，处理日期范围
        if (currentSearchColumn.value === 'create_at') {
            if (currentDateRange.value && Array.isArray(currentDateRange.value) && currentDateRange.value.length === 2) {
                const startDate = currentDateRange.value[0];
                const endDate = currentDateRange.value[1];
                // 格式化日期时间为 YYYY-MM-DD HH:mm:ss 格式
                const formatDateTime = (date) => {
                    const year = date.getFullYear();
                    const month = String(date.getMonth() + 1).padStart(2, '0');
                    const day = String(date.getDate()).padStart(2, '0');
                    const hours = String(date.getHours()).padStart(2, '0');
                    const minutes = String(date.getMinutes()).padStart(2, '0');
                    const seconds = String(date.getSeconds()).padStart(2, '0');
                    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
                };
                columnFilters.value[currentSearchColumn.value] = {
                    start_time: formatDateTime(startDate),
                    end_time: formatDateTime(endDate)
                };
            } else {
                // 如果日期范围为空，移除该列的筛选
                delete columnFilters.value[currentSearchColumn.value];
            }
        } else {
            // 其他列使用文本搜索
            const value = currentSearchValue.value?.trim() || '';
            if (value) {
                columnFilters.value[currentSearchColumn.value] = value;
            } else {
                // 如果值为空，移除该列的筛选
                delete columnFilters.value[currentSearchColumn.value];
            }
        }
        // 重置到第一页
        queryData.value.page = 1;
        fetchUserManageDataList();
    }
    closeSearchPopup();
};

// 重置列搜索
const handleColumnReset = () => {
    if (currentSearchColumn.value) {
        delete columnFilters.value[currentSearchColumn.value];
        // 重置到第一页
        queryData.value.page = 1;
        fetchUserManageDataList();
    }
    closeSearchPopup();
};


// 初始化时加载用户数据和员工、角色列表
onMounted(async () => {
    fetchUserManageDataList();
    // 如果store中没有数据，则加载一次
    if (systemStore.employeeList.length === 0) {
        try {
            await systemStore.fetchEmployeeList();
        } catch (error) {
            console.error("加载员工列表失败:", error);
        }
    }
    if (systemStore.roleList.length === 0) {
        try {
            await systemStore.fetchRoleList();
        } catch (error) {
            console.error("加载角色列表失败:", error);
        }
    }
});
</script>

<style scoped>
:deep(.p-checkbox-input) {
    width: 18px;
    height: 18px;
}

:deep(.p-checkbox-box) {
    width: 18px;
    height: 18px;
}

:deep(.p-datatable-header) {
    background-color: #F3F6F8;
}

:deep(.pi .pi-search .search-icon) {
    scale: .86 !important;
}




.textarea {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    margin-top: 20px;
}

.textarea-wrapper {
    position: relative;
    flex: 1;
    width: 100%;
}

.char-count {
    position: absolute;
    bottom: 8px;
    right: 12px;
    font-size: 12px;
    color: #999999;
    pointer-events: none;
    background-color: rgba(255, 255, 255, 0.9);
    padding: 2px 4px;
}

.w-full {
    width: 270px;
}

.UserManage :deep(.p-select-option.p-select-option-selected.p-focus) {
    background-color: #3067E5;
}

/* 隐藏 PrimeVue 默认排序图标，表头使用 images/login 的 none/top/bottom 图标 */
.UserManage :deep(.p-datatable-thead > tr > th.p--column .p--column-icon) {
    display: none !important;
}

/* 表头右侧：搜索图标 + 排序图标，紧凑排列 */
.header-icons {
    margin-top: 5px;
    display: flex;
    align-items: center;
    gap: 0.125rem;
    flex-shrink: 0;
}

.sort-icon {
    width: 14px;
    height: 14px;
    object-fit: contain;
    cursor: pointer;
    transition: opacity 0.2s;
}

.sort-icon:hover {
    opacity: 0.7;
}

/* .p-inputtext {
    height: 32px;
} */
.p-inputtext,
.p-select,
.p-multiselect,
.p-textarea {
    height: 32px;
    font-weight: 400;
    font-size: 14px;
    color: rgba(0, 0, 0, 0.4);
    line-height: 14px;
}

.UserManage {
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background-color: #F3F6F8;
}

.UserManage :deep(.p-datatable) {
    margin: 5px 16px 16px;
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: #FFFFFF;
    border-radius: 0px 0px 0px 0px;
}

.UserManage :deep(.p-datatable-wrapper) {
    flex: 1;
    overflow: auto;
}

.UserManage :deep(.p-datatable-tbody > tr) {
    cursor: pointer;
}

.UserManage :deep(.p-datatable-tbody > tr:hover) {
    background-color: rgba(0, 0, 0, 0.04);
}

.table-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1.25rem;
}

.table-left-wrapper {
    display: flex;
    align-items: center;
    gap: 24px;
}

.select-all-wrapper {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
}

.select-all-label {
    margin-top: 4px;
    height: 20px;
    font-family: Source Han Sans SC, Source Han Sans SC;
    font-weight: 500;
    font-size: 14px;
    color: #333333;
    line-height: 20px;
    text-align: left;
    font-style: normal;
    text-transform: none;
}

.table-left {
    margin-top: 4px;
    flex: 0 0 auto;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;

    .delItems {
        height: 20px;
        font-family: Source Han Sans SC, Source Han Sans SC;
        font-weight: 500;
        font-size: 14px;
        color: #3067E5;
        line-height: 20px;
        text-align: left;
        font-style: normal;
        text-transform: none;
    }

    .delIcon {
        margin-right: 3px;
        width: 16px;
        height: 16px;

        img {
            width: 100%;
            height: 100%;
        }
    }
}

.table-right {
    margin-right: 14px;
    display: flex;
    align-items: center;
    gap: 16px;
}

.table-center {
    flex: 1;
    max-width: 25rem;
}

.demo-form-inline {
    display: flex;
    gap: 0.625rem;
    align-items: center;
}

.demo-form-inline InputText {
    flex: 1;
}

:deep(.p-datatable-column-sorted) {
    background-color: transparent !important;
    color: inherit !important;
}

.options {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    justify-content: center;
    flex-wrap: nowrap;
}

.options :deep(.p-button) {
    min-width: auto;
    padding: 0.5rem 1rem;
    white-space: nowrap;
}

.options :deep(.p-button-rounded) {
    border-radius: 0.375rem;
}

.p-mr-2 {
    margin-right: 0;
}

.dialog-form {
    /* padding: 1.25rem 0; */
    margin-top: 30px;
}

.form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem 1.5rem;
    max-width: 100%;
}

.form-field {
    display: flex;
    flex-direction: row;
    align-items: center;
    /* gap: 0.75rem; */
}

.form-field.textarea {
    align-items: flex-start;
}

.form-field label {
    flex-shrink: 0;
    white-space: nowrap;
    color: #333333;
    margin-bottom: 0;
    text-align: left;
    width: 100px;
    font-weight: 400;
    font-size: 14px;
    line-height: 22px;
    font-style: normal;
    text-transform: none;
}

.form-field :deep(.p-inputtext),
.form-field :deep(.p-dropdown),
.form-field :deep(.p-multiselect),
.form-field :deep(.p-inputtextarea) {
    flex: 1;
    width: 100%;
    background-color: #ffffff;
    border: 1px solid #e0e0e0;
    border-radius: 4px;
}

.form-field :deep(.p-inputtext:focus),
.form-field :deep(.p-dropdown:not(.p-disabled).p-focus),
.form-field :deep(.p-multiselect:not(.p-disabled).p-focus) {
    border-color: #3067E5;
    box-shadow: 0 0 0 0.2rem rgba(48, 103, 229, 0.25);
}

.form-field :deep(.p-inputtext::placeholder) {
    color: #999999;
    font-size: 14px;
}

@media (max-width: 768px) {
    .form-grid {
        grid-template-columns: 1fr;
    }
}

.department-selector {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    width: 100%;
}

.department-selector :deep(.p-button) {
    width: 100%;
    flex: 1;
}

.department-input {
    flex: 1;
    cursor: pointer;
}

.department-btn {
    flex-shrink: 0;
}

.department-selector-dialog {
    padding: 0;
}

.search-bar {
    margin-bottom: 1rem;
}

.search-bar .search-input {
    width: 100%;
}

.department-tree-container {
    max-height: 450px;
    overflow-y: auto;
    border: 1px solid #dee2e6;
    border-radius: 4px;
    padding: 0.5rem;
}

.department-tree :deep(.ops) {
    display: none !important;
}

.department-tree :deep(.node-content.selected) {
    background-color: #3067E5 !important;
    color: #ffffff !important;
}

.department-tree :deep(.node-content.selected:hover) {
    background-color: #3067E5 !important;
}

.UserManage :deep(.p-datatable-scrollable > .p-datatable-table-container) {
    background-color: #ffffff;
    height: 100%;
}

.UserManage :deep(.p-datatable-gridlines .p-datatable-paginator-bottom) {
    border: none;
}

/* 分页器样式 - 与厂区管理一致 */
.UserManage :deep(.p-paginator) {
    margin: 0 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border: none;
    gap: 16px;
}
.UserManage :deep(.p-paginator .p-paginator-content) {
    display: flex;
    align-items: center;
    gap: 8px;
}
.UserManage :deep(.p-paginator .p-paginator-prev),
.UserManage :deep(.p-paginator .p-paginator-next) {
    background: none;
    border: none;
    padding: 4px 8px;
    color: #3067E5;
    font-size: 14px;
    font-weight: 400;
    box-shadow: none;
}
.UserManage :deep(.p-paginator .p-paginator-prev:disabled),
.UserManage :deep(.p-paginator .p-paginator-next:disabled) {
    color: #adb5bd;
    cursor: not-allowed;
}
.paginator-btn-text {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: Source Han Sans SC, Source Han Sans SC;
}
.UserManage :deep(.p-paginator .p-paginator-pages) {
    display: flex;
    align-items: center;
    gap: 4px;
}
.UserManage :deep(.p-paginator .p-paginator-page) {
    min-width: 32px;
    height: 32px;
    padding: 0 8px;
    background: transparent;
    border: none;
    border-radius: 6px;
    color: #333333;
    font-size: 14px;
    font-weight: 400;
}
.UserManage :deep(.p-paginator .p-paginator-page[data-p-active="true"]),
.UserManage :deep(.p-paginator .p-paginator-page.p-paginator-page-selected) {
    background: #3067E5;
    color: #FFFFFF;
}
.UserManage :deep(.p-paginator .p-paginator-page:not([data-p-active="true"]):hover) {
    background: rgba(0, 0, 0, 0.04);
    color: #333333;
}
.UserManage :deep(.p-paginator .p-paginator-rpp-dropdown),
.UserManage :deep(.p-paginator .p-paginator-rpp-dropdown .p-select) {
    min-width: 60px;
    border: 1px solid #dee2e6;
    border-radius: 4px;
    background: #ffffff;
    font-size: 14px;
}

/* 每页条数下拉展开后，选中项为淡蓝色（下拉层 teleport 到 body，需 :global） */
:global(.p-select-overlay .p-select-option.p-select-option-selected),
:global(.p-select-overlay .p-select-option[data-p-selected="true"]) {
    background: #E6F0FF;
    color: #3067E5;
}

:deep(.p-checkbox .p-checkbox-box) {
    border-color: #3067E5 !important;
}

:deep(.p-checkbox-checked .p-checkbox-box) {
    background-color: #3067E5 !important;
    border-color: #3067E5 !important;
    background: #3067E5 !important;
}

:deep(.p-checkbox .p-checkbox-box.p-highlight:hover) {
    background-color: #2556d1 !important;
    border-color: #2556d1 !important;
}

/* 表头搜索样式 - 紧凑布局：文字与图标、图标之间间距收紧 */
.column-header-with-search {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    /* justify-content: space-between; */
    width: 100%;
}

/* 确保表头文字在所有状态下都可见 */
.column-header-with-search span {
    color: #333333 !important;
    /* flex: 1; */
}

/* 确保排序状态下表头文字也可见 */
.UserManage :deep(.p-datatable-thead > tr > th.p--column .column-header-with-search span),
.UserManage :deep(.p-datatable-thead > tr > th.p--column.p-highlight .column-header-with-search span),
.UserManage :deep(.p-datatable-thead > tr > th.p--column-active .column-header-with-search span) {
    color: #333333 !important;
}

.search-icon {
    cursor: pointer;
    color: #6c757d;
    font-size: 0.875rem;
    transition: color 0.2s;
    padding: 0.0625rem;
}

.search-icon:hover {
    color: #3067E5;
}

/* 列搜索弹窗样式 */
.column-search-popup {
    background: white;
    border-radius: 4px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
    padding: 1rem;
    min-width: 320px;
    max-width: 450px;
    z-index: 1000;
}

.search-popup-input {
    width: 100%;
    margin-bottom: 0.75rem;
    width: 288px;
    border: 1px solid #0052D9;
    border-radius: 3px 3px 3px 3px;
}

.search-popup-input :deep(.p-inputtext) {
    border-color: #3067E5;
}

.search-popup-input :deep(.p-inputtext:focus) {
    border-color: #3067E5;
    box-shadow: 0 0 0 0.2rem rgba(48, 103, 229, 0.25);
}

.search-popup-input :deep(.p-calendar) {
    width: 100%;
}

.search-popup-input :deep(.p-calendar .p-inputtext) {
    border-color: #3067E5;
    width: 100%;
}

.search-popup-input :deep(.p-calendar .p-inputtext:focus) {
    border-color: #3067E5;
    box-shadow: 0 0 0 0.2rem rgba(48, 103, 229, 0.25);
}

.search-popup-input :deep(.p-calendar .p-datepicker-trigger) {
    background-color: #3067E5;
    border-color: #3067E5;
}

.search-popup-input :deep(.p-calendar .p-datepicker-trigger:hover) {
    background-color: #2556d1;
    border-color: #2556d1;
}

.search-popup-buttons {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
}

.search-btn {
    background-color: #3067E5;
    border-color: #3067E5;
}

.search-btn:hover {
    background-color: #2556d1;
    border-color: #2556d1;
}

.reset-btn {
    background-color: white;
    border-color: #dee2e6;
    color: #495057;
}

.reset-btn:hover {
    background-color: #f8f9fa;
    border-color: #adb5bd;
}

/* 搜索弹窗遮罩层 */
.search-popup-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 999;
    background: transparent;
}

.w-full {
    width: 100%;
}

/* 对话框样式：门禁报警记录弹窗使用原生 div 表头，隐藏自带的 p-dialog-header */
.UserManage :deep(.user-manage-dialog .p-dialog-header),
:global(.user-manage-dialog .p-dialog-header) {
    display: none !important;
}

.UserManage :deep(.p-dialog-header) {
    background-color: #ffffff;
    border-bottom: 1px solid green;
    padding: 1rem 1.5rem;
}

.dialog_header {
    height: 55px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid #E7E7E7;
    margin: 0 -1.5rem 20px -1.5rem;
    padding: 0 1.5rem;

    /* 原生 div 表头（替代 p-dialog-header） */
    .dialog-header-custom {
        margin-left: -5px;
        height: 24px;
        font-family: Source Han Sans SC, Source Han Sans SC;
        font-weight: 500;
        font-size: 16px;
        color: rgba(0, 0, 0, 0.9);
        line-height: 24px;
        text-align: left;
        font-style: normal;
        text-transform: none;
    }
}



:deep(.p-dialog-header .p-dialog-title) {
    color: red !important;
}

.UserManage :deep(.p-dialog-header-icon) {
    display: none !important;
}

.UserManage :deep(.p-dialog-header-icon:hover) {
    background-color: #2556d1;
}

.UserManage :deep(.p-dialog-header-icon .p-dialog-header-icon-icon) {
    color: #ffffff;
    font-size: 14px;
}

.UserManage :deep(.p-dialog-content) {
    background-color: #f8f9fa;
    padding: 1.5rem;
    border-top: 1px solid green !important;
}

/* 仅隐藏新增/编辑用户弹窗底部的横向滚动条（弹窗 portaled 到 body，需用 :global） */
:global(.user-manage-dialog .p-dialog-content) {
    overflow-x: hidden !important;
}

:global(.user-manage-dialog.p-dialog) {
    overflow-x: hidden !important;
}

.UserManage :deep(.p-dialog-footer) {
    background-color: #ffffff;
    border-top: 1px solid red !important;
    padding: 1rem 1.5rem;
    display: flex;
    justify-content: flex-end;
    gap: 0.75rem;
}

.dialog-close-btn,
.dialog-confirm-btn {
    background-color: #3067E5;
    border-color: #3067E5;
    color: #ffffff;
    border-radius: 4px;
    padding: 0.5rem 1.25rem;
    font-weight: 400;
    transition: background-color 0.2s, border-color 0.2s;
}

.dialog-close-btn:hover,
.dialog-confirm-btn:hover {
    background-color: #2556d1;
    border-color: #2556d1;
}

.dialog-close-btn :deep(.p-button-icon),
.dialog-confirm-btn :deep(.p-button-icon) {
    color: #ffffff;
    margin-right: 0.5rem;
}

:deep(.p-textarea) {
    height: 170px;
}

.select-all-label-paginator {
    height: 19px;
    font-family: Source Han Sans SC, Source Han Sans SC;
    font-weight: 400;
    font-size: 14px;
    color: rgba(0, 0, 0, 0.6);
    line-height: 22px;
    text-align: left;
    font-style: normal;
    text-transform: none;
}

:deep(.p-datatable-gridlines .p-datatable-paginator-bottom) {
    border: none;
}

.footer_box {
    margin-top: 32px;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    display: flex;
    flex-direction: row-reverse;
    border-top: 1px solid #E7E7E7;
    padding-top: 12px;
    height: 55px;
    /* background: #f8f9fa;  */
    z-index: 1;
}

/* .footer_box::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -20px;
    height: 20px;
    background: #f8f9fa;
    z-index: 1;
} */
:global(.datepicker-panel-scale-07.p-datepicker-panel) {
    transform: scale(0.7);
    transform-origin: top left;
}
:global(.datepicker-panel-scale-07.p-datepicker-panel .p-datepicker-day.p-datepicker-day-selected),
:global(.datepicker-panel-scale-07.p-datepicker-panel .p-datepicker-today > .p-datepicker-day.p-datepicker-day-selected) {
    background: #3067E5 !important;
    color: #fff !important;
}
.footer_box .btn {
    display: flex;
    margin-right: 16px;

    .ancle {
        cursor: pointer;
        width: 60px;
        height: 32px;
        background: #E7E7E7;
        border-radius: 3px 3px 3px 3px;
        text-align: center;
        line-height: 32px;
        font-weight: 400;
        font-size: 14px;
        color: rgba(0, 0, 0, 0.9);
        text-align: center;
        font-style: normal;
        text-transform: none;
        margin-right: 8px;
    }

    .confirm {
        cursor: pointer;
        width: 60px;
        height: 32px;
        background: #3067E5;
        border-radius: 3px 3px 3px 3px;
        text-align: center;
        line-height: 32px;
        font-family: PingFang SC, PingFang SC;
        font-weight: 400;
        font-size: 14px;
        color: rgba(255, 255, 255, 0.9);
        text-align: center;
        font-style: normal;
        text-transform: none;
    }
}

.delete-dialog-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.5);
}

.del_box {
    cursor: pointer;
    width: 480px;
    height: 172px;
    background: #FFFFFF;
    border-radius: 4px 4px 4px 4px;

    .header {
        margin-top: 28px;
        margin-left: 32px;
        display: flex;
        align-items: center;
        justify-content: space-between;

        .left {
            display: flex;
        }

        .img_box {
            width: 24px;
            height: 24px;

            img {
                width: 100%;
                height: 100%;
            }
        }

        .del_name {
            margin-left: 8px;
            height: 24px;
            font-family: Source Han Sans SC, Source Han Sans SC;
            font-weight: 500;
            font-size: 16px;
            color: rgba(0, 0, 0, 0.9);
            line-height: 24px;
            text-align: left;
            font-style: normal;
            text-transform: none;
        }

        .del_icon {
            width: 16px;
            height: 16px;
            margin-right: 24px;

            img {
                width: 100%;
                height: 100%;
            }
        }
    }

    .delText {
        margin-top: 16px;
        margin-left: 64px;
        height: 22px;
        font-family: Source Han Sans SC, Source Han Sans SC;
        font-weight: 400;
        font-size: 14px;
        color: rgba(0, 0, 0, 0.6);
        line-height: 22px;
        text-align: left;
        font-style: normal;
        text-transform: none;
    }

    .del-btn {
        margin-top: 26px;
        margin-left: 320px;
        display: flex;

        .btnAncle {
            width: 60px;
            height: 32px;
            line-height: 32px;
            text-align: center;
            background: #E7E7E7;
            border-radius: 3px 3px 3px 3px;
            font-weight: 400;
            font-size: 14px;
            color: rgba(0, 0, 0, 0.9);
            margin-right: 8px;
        }

        .btnOk {
            width: 60px;
            height: 32px;
            text-align: center;
            background: #3067E5;
            border-radius: 3px 3px 3px 3px;
            font-weight: 400;
            font-size: 14px;
            color: rgba(255, 255, 255, 0.9);
            line-height: 32px;
        }
    }
}

:deep(.p-checkbox-input) {
    margin-top: 4px;
    width: 16px;
    height: 16px;
}

:deep(.p-checkbox-box) {
    margin-top: 4px;
    width: 16px;
    height: 16px;
}

:deep(.p-datatable-tbody > tr > td) {
    height: 22px;
    font-family: Source Han Sans SC, Source Han Sans SC;
    font-weight: 400;
    font-size: 14px;
    color: #666666;
    line-height: 22px;
    text-align: left;
    font-style: normal;
    text-transform: none;
}

:deep(.column-header-with-search span) {
    font-family: Source Han Sans SC, Source Han Sans SC;
    font-weight: 500;
    font-size: 14px;
    color: #333333 !important;
    line-height: 22px;
    text-align: left;
    font-style: normal;
    text-transform: none;
}
:deep(.p-checkbox-input) {
    margin-top: 4px;
    width: 16px;
    height: 16px;
}

:deep(.p-checkbox-box) {
    margin-top: 4px;
    width: 16px;
    height: 16px;
}

.search-popup-buttons {
    cursor: pointer;
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    .search_reset {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 60px;
        height: 32px;
        background: #E7E7E7;
        border-radius: 3px 3px 3px 3px;
        font-family: Source Han Sans SC, Source Han Sans SC;
        font-weight: 400;
        font-size: 14px;
        color: rgba(0,0,0,0.9);
        line-height: 22px;
        text-align: center;
        font-style: normal;
        text-transform: none;
    }
    .search-btn {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 60px;
        height: 32px;
        background: #0052D9;
        border-radius: 3px 3px 3px 3px;
        font-family: Source Han Sans SC, Source Han Sans SC;
        font-weight: 400;
        font-size: 14px;
        color: rgba(255,255,255,0.9);
        line-height: 22px;
        text-align: center;
        font-style: normal;
        text-transform: none;
    }
}

.search-btn {
    background-color: #3067E5;
    border-color: #3067E5;
}

.search-btn:hover {
    background-color: #2556d1;
    border-color: #2556d1;
}

.reset-btn {
    background-color: white;
    border-color: #dee2e6;
    color: #495057;
}
.search-popup-input :deep(.p-inputtext) {
    width: 288px;
    height: 36px;
    border-radius: 3px 3px 3px 3px;
    border-color: #3067E5;
}

.search-popup-input :deep(.p-inputtext:focus) {
    /* border-color: #3067E5; */
    border: 1px solid #0052D9;
}

/* 失败提示 - 与资产台账一致：右上角、原生样式 */
.edit-fail-toast {
    position: fixed;
    top: 24px;
    right: 24px;
    z-index: 9999;
    gap: 12px;
    padding: 16px 24px 24px 24px;
    width: 400px;
    height: 98px;
    border-radius: 4px;
    background: #ffffff;
    box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, 0.08), 0px 16px 24px 2px rgba(0, 0, 0, 0.04), 0px 6px 30px 5px rgba(0, 0, 0, 0.05);
    border: 1px solid rgba(0, 0, 0, 0.06);
}
.totast_wrapper { display: flex; justify-content: space-between; }
.left_box { display: flex; }
.edit-fail-toast-icon { flex-shrink: 0; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; }
.edit-fail-toast-icon img { width: 24px; height: 24px; object-fit: contain; }
.edit-fail-toast-content { flex: 1; padding-right: 8px; position: absolute; left: 57px; margin-top: 8px; }
.edit-fail-toast-title { font-size: 16px; font-weight: 600; color: rgba(0, 0, 0, 0.85); line-height: 1.4; margin-left: 8px; margin-top: 2px; }
.edit-fail-toast-detail { margin-top: 4px; font-size: 14px; font-weight: 400; color: rgba(0, 0, 0, 0.45); line-height: 1.5; }
.edit-fail-toast-close { flex-shrink: 0; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: rgba(0, 0, 0, 0.45); }
.edit-fail-toast-close:hover { color: rgba(0, 0, 0, 0.65); }
.edit-fail-toast-close img { width: 14px; height: 14px; object-fit: contain; }

/* 成功提示 - 与失败提示统一：右上角、左对齐布局 */
.edit-success-toast {
    position: fixed;
    top: 24px;
    right: 24px;
    z-index: 9999;
    width: 400px;
    border-radius: 4px;
    padding: 16px 24px 24px 24px;
    background: #ffffff;
    box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, 0.08), 0px 16px 24px 2px rgba(0, 0, 0, 0.04), 0px 6px 30px 5px rgba(0, 0, 0, 0.05);
    border: 1px solid rgba(0, 0, 0, 0.06);
    text-align: left;
}
.edit-success-toast .totast_wrapper { display: flex; justify-content: space-between; align-items: flex-start; }
.edit-success-toast .left_box { display: flex; align-items: flex-start; gap: 8px; }
.edit-success-toast-icon { flex-shrink: 0; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; }
.edit-success-toast-icon img { width: 24px; height: 24px; object-fit: contain; }
.edit-success-toast-title { font-size: 16px; font-weight: 600; color: rgba(0, 0, 0, 0.85); line-height: 1.4; margin-top: 2px; }
.edit-success-toast-content { padding-right: 8px; margin-top: 8px; margin-left: 32px; }
.edit-success-toast-detail { margin-top: 4px; font-size: 14px; font-weight: 400; color: rgba(0, 0, 0, 0.45); line-height: 1.5; }
.edit-success-toast-close { flex-shrink: 0; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: rgba(0, 0, 0, 0.45); }
.edit-success-toast-close:hover { color: rgba(0, 0, 0, 0.65); }
.edit-success-toast-close img { width: 14px; height: 14px; object-fit: contain; }
</style>
