将整套 web 源码纳入仓库,并为 web/node_modules、构建产物及本地环境文件配置 .gitignore,同时移除占位用的 assets/.gitkeep。 Co-authored-by: Cursor <cursoragent@cursor.com>
2027 lines
66 KiB
Vue
2027 lines
66 KiB
Vue
<!-- 门禁报警记录 - 公共组件 -->
|
||
<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}个角色`;
|
||
});
|
||
|
||
// 计算 描述信息字符数
|
||
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>
|