|
|
@@ -0,0 +1,1233 @@
|
|
|
+<template>
|
|
|
+ <div class="ledger-container">
|
|
|
+ <!-- 左侧树形导航 -->
|
|
|
+ <div class="sidebar">
|
|
|
+ <div class="sidebar-header">
|
|
|
+ <h3 class="sidebar-title">
|
|
|
+ <i class="el-icon-location-outline"></i>
|
|
|
+ 服务区域
|
|
|
+ </h3>
|
|
|
+ </div>
|
|
|
+ <div class="search-box">
|
|
|
+ <el-input
|
|
|
+ v-model="areaName"
|
|
|
+ placeholder="搜索服务区..."
|
|
|
+ clearable
|
|
|
+ prefix-icon="el-icon-search"
|
|
|
+ @input="filterTree"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="tree-wrapper">
|
|
|
+ <el-tree
|
|
|
+ ref="tree"
|
|
|
+ :data="areaOptions"
|
|
|
+ :props="defaultProps"
|
|
|
+ :expand-on-click-node="false"
|
|
|
+ :filter-node-method="filterNode"
|
|
|
+ node-key="id"
|
|
|
+ :default-expanded-keys="defaultExpandedKeys"
|
|
|
+ highlight-current
|
|
|
+ @node-click="handleNodeClick"
|
|
|
+ >
|
|
|
+ <template #default="{ node, data }">
|
|
|
+ <span class="tree-node">
|
|
|
+ <i :class="getTreeIcon(data)" class="node-icon"></i>
|
|
|
+ <span class="node-label">{{ node.label }}</span>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-tree>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 右侧内容区 -->
|
|
|
+ <div class="main-content">
|
|
|
+ <!-- 搜索筛选区 -->
|
|
|
+ <transition name="slide-fade">
|
|
|
+ <div class="filter-section" v-show="showSearch">
|
|
|
+ <el-form :model="queryParams" ref="queryForm" :inline="true" class="filter-form">
|
|
|
+ <el-form-item label="目标对象" prop="objName">
|
|
|
+ <el-input
|
|
|
+ v-model="queryParams.objName"
|
|
|
+ placeholder="输入对象名称"
|
|
|
+ clearable
|
|
|
+ @keyup.enter.native="handleQuery"
|
|
|
+ >
|
|
|
+ <template #prefix>
|
|
|
+ <i class="el-icon-aim"></i>
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="创建时间">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="queryParams.recordTimeRange"
|
|
|
+ type="daterange"
|
|
|
+ range-separator="至"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ :picker-options="pickerOptions"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="维护标题" prop="maintainTitle">
|
|
|
+ <el-input
|
|
|
+ v-model="queryParams.maintainTitle"
|
|
|
+ placeholder="输入维护标题"
|
|
|
+ clearable
|
|
|
+ @keyup.enter.native="handleQuery"
|
|
|
+ >
|
|
|
+ <template #prefix>
|
|
|
+ <i class="el-icon-document"></i>
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="维护人" prop="maintainPerson">
|
|
|
+ <el-input
|
|
|
+ v-model="queryParams.maintainPerson"
|
|
|
+ placeholder="输入维护人"
|
|
|
+ clearable
|
|
|
+ @keyup.enter.native="handleQuery"
|
|
|
+ >
|
|
|
+ <template #prefix>
|
|
|
+ <i class="el-icon-user"></i>
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item class="filter-buttons">
|
|
|
+ <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
|
|
+ <el-button icon="el-icon-refresh-left" @click="resetQuery">重置</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ </transition>
|
|
|
+
|
|
|
+ <!-- 工具栏 -->
|
|
|
+ <div class="toolbar">
|
|
|
+ <div class="toolbar-left">
|
|
|
+ <el-button type="primary" icon="el-icon-plus" @click="handleAdd" v-hasPermi="['ems:ledger:add']">
|
|
|
+ 新增台账
|
|
|
+ </el-button>
|
|
|
+ <el-button type="warning" icon="el-icon-download" plain @click="handleExport" v-hasPermi="['ems:ledger:export']">
|
|
|
+ 导出
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ <div class="toolbar-right">
|
|
|
+ <el-tooltip content="刷新" placement="top">
|
|
|
+ <el-button circle icon="el-icon-refresh" @click="getList(true)" />
|
|
|
+ </el-tooltip>
|
|
|
+ <el-tooltip :content="showSearch ? '隐藏筛选' : '显示筛选'" placement="top">
|
|
|
+ <el-button circle :icon="showSearch ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" @click="showSearch = !showSearch" />
|
|
|
+ </el-tooltip>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 数据表格 -->
|
|
|
+ <div class="table-wrapper">
|
|
|
+ <el-table
|
|
|
+ v-loading="loading"
|
|
|
+ :data="ledgerList"
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
+ :header-cell-style="{ background: '#f8fafc', color: '#475569', fontWeight: '600' }"
|
|
|
+ stripe
|
|
|
+ >
|
|
|
+ <el-table-column type="selection" width="50" align="center" />
|
|
|
+ <el-table-column label="园区名称" align="left" prop="areaName" min-width="140">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div class="cell-area">
|
|
|
+ <i class="el-icon-office-building"></i>
|
|
|
+ <span>{{ row.areaName || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="记录编号" align="center" prop="recordCode" min-width="150">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-tag size="small" effect="plain">{{ row.recordCode }}</el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="目标对象" align="left" prop="objName" min-width="160">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div class="cell-object">
|
|
|
+ <span class="obj-name">{{ row.objName || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="安装位置" align="left" prop="insLocation" min-width="180" show-overflow-tooltip />
|
|
|
+ <el-table-column label="维护标题" align="left" prop="maintainTitle" min-width="200" show-overflow-tooltip>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="maintain-title">{{ row.maintainTitle }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="创建时间" align="center" prop="recordTime" width="120">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="date-text">{{ parseTime(row.recordTime, '{y}-{m}-{d}') }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column label="操作" align="center" width="200" fixed="right">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div class="action-buttons">
|
|
|
+ <el-button type="text" icon="el-icon-view" @click="handleView(row)">查看</el-button>
|
|
|
+ <el-button type="text" icon="el-icon-edit" @click="handleEdit(row)" v-hasPermi="['ems:ledger:edit']">编辑</el-button>
|
|
|
+ <el-button type="text" icon="el-icon-delete" class="danger-btn" @click="handleDelete(row)" v-hasPermi="['ems:ledger:remove']">删除</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 分页 -->
|
|
|
+ <div class="pagination-wrapper" v-show="total > 0">
|
|
|
+ <el-pagination
|
|
|
+ background
|
|
|
+ :current-page.sync="queryParams.pageNum"
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
+ :page-size.sync="queryParams.pageSize"
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ :total="total"
|
|
|
+ @size-change="getList"
|
|
|
+ @current-change="getList"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 新增/编辑对话框 -->
|
|
|
+ <el-dialog
|
|
|
+ :title="dialogTitle"
|
|
|
+ :visible.sync="dialogVisible"
|
|
|
+ width="720px"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ custom-class="ledger-dialog"
|
|
|
+ append-to-body
|
|
|
+ @open="onDialogOpen"
|
|
|
+ >
|
|
|
+ <el-form ref="ledgerForm" :model="form" :rules="rules" label-width="100px" class="ledger-form">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="记录编号" prop="recordCode">
|
|
|
+ <el-input v-model="form.recordCode" placeholder="自动生成" :disabled="isView">
|
|
|
+ <template #append v-if="!isView && !form.id">
|
|
|
+ <el-button icon="el-icon-refresh" @click="generateCode">生成</el-button>
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="创建时间" prop="recordTime">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="form.recordTime"
|
|
|
+ type="date"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ placeholder="选择日期"
|
|
|
+ style="width: 100%"
|
|
|
+ :disabled="isView"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <!-- 对象类型:只有设施和设备 -->
|
|
|
+ <el-form-item label="对象类型" prop="objType">
|
|
|
+ <el-radio-group v-model="form.objType" @change="handleObjTypeChange" :disabled="isView">
|
|
|
+ <el-radio-button label="3">
|
|
|
+ <i class="el-icon-office-building"></i>
|
|
|
+ 设施
|
|
|
+ </el-radio-button>
|
|
|
+ <el-radio-button label="2">
|
|
|
+ <i class="el-icon-cpu"></i>
|
|
|
+ 设备
|
|
|
+ </el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 台账对象选择 -->
|
|
|
+ <el-form-item label="台账对象" prop="objCode" v-if="form.objType && !isView">
|
|
|
+ <!-- 设施类型 -->
|
|
|
+ <template v-if="form.objType === '3'">
|
|
|
+ <el-select
|
|
|
+ v-model="form.objCode"
|
|
|
+ placeholder="请选择设施"
|
|
|
+ filterable
|
|
|
+ @change="handleFacsSelect"
|
|
|
+ clearable
|
|
|
+ style="width: 100%"
|
|
|
+ :loading="facsLoading"
|
|
|
+ >
|
|
|
+ <el-option-group
|
|
|
+ v-for="group in facsGroupList"
|
|
|
+ :key="group.category"
|
|
|
+ :label="group.categoryName"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in group.children"
|
|
|
+ :key="item.facsCode"
|
|
|
+ :label="item.facsName"
|
|
|
+ :value="item.facsCode"
|
|
|
+ >
|
|
|
+ <div class="select-option">
|
|
|
+ <span class="option-name">{{ item.facsName }}</span>
|
|
|
+ <span class="option-extra">{{ item.refAreaName }}</span>
|
|
|
+ </div>
|
|
|
+ </el-option>
|
|
|
+ </el-option-group>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 设备类型 - 分类和设备在一行 -->
|
|
|
+ <template v-else-if="form.objType === '2'">
|
|
|
+ <div class="device-select-row">
|
|
|
+ <el-select
|
|
|
+ v-model="form.deviceCategory"
|
|
|
+ placeholder="设备分类"
|
|
|
+ @change="handleDeviceCategoryChange"
|
|
|
+ clearable
|
|
|
+ class="category-select"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in deviceCategoryOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ >
|
|
|
+ <span><i :class="item.icon" style="margin-right: 5px;"></i>{{ item.label }}</span>
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ <el-select
|
|
|
+ v-model="form.objCode"
|
|
|
+ placeholder="请选择设备"
|
|
|
+ filterable
|
|
|
+ :loading="deviceLoading"
|
|
|
+ @change="handleDeviceSelect"
|
|
|
+ clearable
|
|
|
+ class="device-select"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in deviceList"
|
|
|
+ :key="item.deviceCode"
|
|
|
+ :label="item.deviceName"
|
|
|
+ :value="item.deviceCode"
|
|
|
+ >
|
|
|
+ <div class="select-option">
|
|
|
+ <span class="option-name">{{ item.deviceName }}</span>
|
|
|
+ <span class="option-extra">{{ item.location || item.locationRefName }}</span>
|
|
|
+ </div>
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 查看模式显示对象信息 -->
|
|
|
+ <el-form-item label="台账对象" v-if="isView && form.objName">
|
|
|
+ <el-input :value="form.objName" disabled />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="安装位置" prop="insLocation">
|
|
|
+ <el-input v-model="form.insLocation" placeholder="选择台账对象后自动填充" :disabled="isView" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="维护标题" prop="maintainTitle">
|
|
|
+ <el-input v-model="form.maintainTitle" placeholder="请输入维护标题" :disabled="isView" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="维护内容">
|
|
|
+ <div v-if="isView" class="view-content" v-html="form.maintainContent || '暂无内容'"></div>
|
|
|
+ <editor v-else v-model="form.maintainContent" :min-height="200" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item label="维护人" prop="maintainPerson">
|
|
|
+ <el-input v-model="form.maintainPerson" placeholder="请输入维护人" :disabled="isView" style="width: 200px" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="dialogVisible = false">取 消</el-button>
|
|
|
+ <el-button v-if="!isView" type="primary" :loading="submitLoading" @click="submitForm">
|
|
|
+ 确 定
|
|
|
+ </el-button>
|
|
|
+ <el-button v-else type="primary" @click="switchToEdit" v-hasPermi="['ems:ledger:edit']">
|
|
|
+ 编 辑
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { listLedger, getLedger, addLedger, updateLedger, delLedger, generateRecordCode } from '@/api/device/ledger'
|
|
|
+import { listDevRecursionByArea } from '@/api/device/device'
|
|
|
+import { listAllFacs } from '@/api/basecfg/emsfacs'
|
|
|
+import { areaTreeSelect } from '@/api/basecfg/area'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'Ledger',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ // 加载状态
|
|
|
+ loading: false,
|
|
|
+ submitLoading: false,
|
|
|
+ deviceLoading: false,
|
|
|
+ facsLoading: false,
|
|
|
+
|
|
|
+ // 显示控制
|
|
|
+ showSearch: true,
|
|
|
+ dialogVisible: false,
|
|
|
+ dialogTitle: '',
|
|
|
+ isView: false,
|
|
|
+
|
|
|
+ // 列表数据
|
|
|
+ ledgerList: [],
|
|
|
+ total: 0,
|
|
|
+ ids: [],
|
|
|
+
|
|
|
+ // 左侧树形数据
|
|
|
+ areaOptions: [],
|
|
|
+ areaName: '',
|
|
|
+ defaultExpandedKeys: [],
|
|
|
+ defaultProps: {
|
|
|
+ children: 'children',
|
|
|
+ label: 'label'
|
|
|
+ },
|
|
|
+
|
|
|
+ // 设施数据
|
|
|
+ facsList: [],
|
|
|
+ facsGroupList: [],
|
|
|
+
|
|
|
+ // 设备数据
|
|
|
+ deviceList: [],
|
|
|
+
|
|
|
+ // 设备分类选项
|
|
|
+ deviceCategoryOptions: [
|
|
|
+ { value: 'E', label: '产能设备', icon: 'el-icon-sunny' },
|
|
|
+ { value: 'C', label: '储能设备', icon: 'el-icon-coin' },
|
|
|
+ { value: 'W', label: '输配设备', icon: 'el-icon-connection' },
|
|
|
+ { value: 'Z', label: '用能设备', icon: 'el-icon-lightning' }
|
|
|
+ ],
|
|
|
+
|
|
|
+ // 查询参数
|
|
|
+ queryParams: {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ objType: '3', // 默认设施
|
|
|
+ objName: null,
|
|
|
+ maintainTitle: null,
|
|
|
+ maintainPerson: null,
|
|
|
+ recordTimeRange: [],
|
|
|
+ areaCode: ''
|
|
|
+ },
|
|
|
+
|
|
|
+ // 表单数据
|
|
|
+ form: {},
|
|
|
+
|
|
|
+ // 表单校验
|
|
|
+ rules: {
|
|
|
+ recordCode: [{ required: true, message: '记录编号不能为空', trigger: 'blur' }],
|
|
|
+ objType: [{ required: true, message: '请选择对象类型', trigger: 'change' }],
|
|
|
+ maintainTitle: [{ required: true, message: '维护标题不能为空', trigger: 'blur' }],
|
|
|
+ recordTime: [{ required: true, message: '请选择日期', trigger: 'change' }]
|
|
|
+ },
|
|
|
+
|
|
|
+ // 日期选择器配置
|
|
|
+ pickerOptions: {
|
|
|
+ shortcuts: [
|
|
|
+ {
|
|
|
+ text: '最近一周',
|
|
|
+ onClick(picker) {
|
|
|
+ const end = new Date()
|
|
|
+ const start = new Date()
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
|
|
|
+ picker.$emit('pick', [start, end])
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '最近一月',
|
|
|
+ onClick(picker) {
|
|
|
+ const end = new Date()
|
|
|
+ const start = new Date()
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
|
|
|
+ picker.$emit('pick', [start, end])
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '最近三月',
|
|
|
+ onClick(picker) {
|
|
|
+ const end = new Date()
|
|
|
+ const start = new Date()
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
|
|
|
+ picker.$emit('pick', [start, end])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ async created() {
|
|
|
+ // 加载左侧区域树(用于筛选)
|
|
|
+ await this.getAreaTree()
|
|
|
+ // 预加载设施列表
|
|
|
+ await this.loadFacsList()
|
|
|
+ // 加载台账列表
|
|
|
+ this.getList(true)
|
|
|
+ },
|
|
|
+
|
|
|
+ watch: {
|
|
|
+ areaName(val) {
|
|
|
+ this.$refs.tree.filter(val)
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ methods: {
|
|
|
+ // 获取树节点图标
|
|
|
+ getTreeIcon(data) {
|
|
|
+ if (data.id === '-1') return 'el-icon-s-home'
|
|
|
+ return 'el-icon-office-building'
|
|
|
+ },
|
|
|
+
|
|
|
+ // 过滤树节点
|
|
|
+ filterTree() {
|
|
|
+ this.$refs.tree.filter(this.areaName)
|
|
|
+ },
|
|
|
+
|
|
|
+ filterNode(value, data) {
|
|
|
+ if (!value) return true
|
|
|
+ return data.label.indexOf(value) !== -1
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取左侧区域树(用于数据筛选)
|
|
|
+ async getAreaTree() {
|
|
|
+ try {
|
|
|
+ const response = await areaTreeSelect('0', 1)
|
|
|
+ this.areaOptions = [{
|
|
|
+ id: '-1',
|
|
|
+ label: '全部',
|
|
|
+ children: []
|
|
|
+ }].concat(response.data || [])
|
|
|
+ this.defaultExpandedKeys = ['-1']
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.tree) {
|
|
|
+ this.$refs.tree.setCurrentKey('-1')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取区域树失败:', error)
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 加载设施列表
|
|
|
+ async loadFacsList() {
|
|
|
+ this.facsLoading = true
|
|
|
+ try {
|
|
|
+ const response = await listAllFacs()
|
|
|
+ this.facsList = response.data || []
|
|
|
+ // 按分类分组
|
|
|
+ const grouped = {}
|
|
|
+ this.facsList.forEach(item => {
|
|
|
+ const key = item.facsCategory
|
|
|
+ if (!grouped[key]) {
|
|
|
+ grouped[key] = {
|
|
|
+ category: key,
|
|
|
+ categoryName: item.facsCategoryName,
|
|
|
+ children: []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ grouped[key].children.push(item)
|
|
|
+ })
|
|
|
+ this.facsGroupList = Object.values(grouped)
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载设施列表失败:', error)
|
|
|
+ this.facsList = []
|
|
|
+ this.facsGroupList = []
|
|
|
+ } finally {
|
|
|
+ this.facsLoading = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 加载设备列表
|
|
|
+ async loadDeviceList(category) {
|
|
|
+ this.deviceLoading = true
|
|
|
+ this.deviceList = []
|
|
|
+ try {
|
|
|
+ const params = {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 9999
|
|
|
+ }
|
|
|
+ // 如果有分类则按分类筛选
|
|
|
+ if (category) {
|
|
|
+ params.deviceCategory = category
|
|
|
+ }
|
|
|
+ // 如果左侧树选中了区域,按区域筛选
|
|
|
+ if (this.queryParams.areaCode && this.queryParams.areaCode !== '-1' && this.queryParams.areaCode !== '') {
|
|
|
+ params.locationRef = this.queryParams.areaCode
|
|
|
+ }
|
|
|
+ const response = await listDevRecursionByArea(params)
|
|
|
+ this.deviceList = response.rows || []
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载设备列表失败:', error)
|
|
|
+ this.deviceList = []
|
|
|
+ } finally {
|
|
|
+ this.deviceLoading = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 左侧树节点点击
|
|
|
+ handleNodeClick(data) {
|
|
|
+ this.queryParams.areaCode = data.id === '-1' ? '' : data.id
|
|
|
+ this.handleQuery()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取台账列表
|
|
|
+ getList(refresh = false) {
|
|
|
+ if (refresh) {
|
|
|
+ this.queryParams.pageNum = 1
|
|
|
+ }
|
|
|
+ this.loading = true
|
|
|
+ listLedger(this.queryParams).then(response => {
|
|
|
+ this.ledgerList = response.rows || []
|
|
|
+ this.total = response.total || 0
|
|
|
+ }).finally(() => {
|
|
|
+ this.loading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 搜索
|
|
|
+ handleQuery() {
|
|
|
+ this.queryParams.pageNum = 1
|
|
|
+ this.getList()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 重置
|
|
|
+ resetQuery() {
|
|
|
+ this.resetForm('queryForm')
|
|
|
+ this.queryParams.recordTimeRange = []
|
|
|
+ this.handleQuery()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 切换顶部Tab
|
|
|
+ switchTab(type) {
|
|
|
+ this.queryParams.objType = type
|
|
|
+ this.resetQuery()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 多选
|
|
|
+ handleSelectionChange(selection) {
|
|
|
+ this.ids = selection.map(item => item.id)
|
|
|
+ },
|
|
|
+
|
|
|
+ // 重置表单
|
|
|
+ resetForm(formName) {
|
|
|
+ if (this.$refs[formName]) {
|
|
|
+ this.$refs[formName].resetFields()
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 初始化表单
|
|
|
+ initForm() {
|
|
|
+ this.form = {
|
|
|
+ id: null,
|
|
|
+ recordCode: '',
|
|
|
+ objType: '3', // 默认设施
|
|
|
+ objCode: null,
|
|
|
+ objName: '',
|
|
|
+ recordTime: null,
|
|
|
+ insLocation: '',
|
|
|
+ maintainTitle: '',
|
|
|
+ maintainContent: '',
|
|
|
+ maintainPerson: '',
|
|
|
+ deviceCategory: null,
|
|
|
+ areaCode: '' // 区域编码
|
|
|
+ }
|
|
|
+ this.deviceList = []
|
|
|
+ },
|
|
|
+
|
|
|
+ // 生成编号
|
|
|
+ generateCode() {
|
|
|
+ this.form.recordCode = generateRecordCode()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 对话框打开时
|
|
|
+ onDialogOpen() {
|
|
|
+ // 确保设施列表已加载(默认是设施类型)
|
|
|
+ if (!this.isView && this.form.objType === '3') {
|
|
|
+ if (this.facsGroupList.length === 0) {
|
|
|
+ this.loadFacsList()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 对象类型变更
|
|
|
+ handleObjTypeChange(type) {
|
|
|
+ // 清空选择
|
|
|
+ this.form.objCode = null
|
|
|
+ this.form.objName = ''
|
|
|
+ this.form.insLocation = ''
|
|
|
+ this.form.deviceCategory = null
|
|
|
+ this.deviceList = []
|
|
|
+
|
|
|
+ if (type === '3') {
|
|
|
+ // 设施类型 - 确保设施列表已加载
|
|
|
+ if (this.facsGroupList.length === 0) {
|
|
|
+ this.loadFacsList()
|
|
|
+ }
|
|
|
+ } else if (type === '2') {
|
|
|
+ // 设备类型 - 加载全部设备
|
|
|
+ this.loadDeviceList('')
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 设备分类变更
|
|
|
+ handleDeviceCategoryChange(category) {
|
|
|
+ this.form.objCode = null
|
|
|
+ this.form.objName = ''
|
|
|
+ this.form.insLocation = ''
|
|
|
+ this.loadDeviceList(category)
|
|
|
+ },
|
|
|
+
|
|
|
+ // 设施选择
|
|
|
+ handleFacsSelect(facsCode) {
|
|
|
+ const facs = this.facsList.find(f => f.facsCode === facsCode)
|
|
|
+ if (facs) {
|
|
|
+ this.form.objName = facs.facsName
|
|
|
+ this.form.insLocation = facs.refAreaName || ''
|
|
|
+ this.form.areaCode = facs.refArea || '' // 设施的区域编码
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 设备选择
|
|
|
+ handleDeviceSelect(deviceCode) {
|
|
|
+ const device = this.deviceList.find(d => d.deviceCode === deviceCode)
|
|
|
+ if (device) {
|
|
|
+ this.form.objName = device.deviceName
|
|
|
+ this.form.insLocation = device.location || device.areaPath || device.locationRefName || ''
|
|
|
+ this.form.areaCode = device.areaCode || device.locationRef || '' // 设备的区域编码
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 新增
|
|
|
+ handleAdd() {
|
|
|
+ this.initForm()
|
|
|
+ this.generateCode()
|
|
|
+ this.form.recordTime = this.parseTime(new Date(), '{y}-{m}-{d}')
|
|
|
+ this.dialogTitle = '新增设备台账'
|
|
|
+ this.isView = false
|
|
|
+ this.dialogVisible = true
|
|
|
+ },
|
|
|
+
|
|
|
+ // 查看
|
|
|
+ handleView(row) {
|
|
|
+ this.initForm()
|
|
|
+ getLedger(row.id).then(response => {
|
|
|
+ this.form = { ...response.data }
|
|
|
+ this.dialogTitle = '查看设备台账'
|
|
|
+ this.isView = true
|
|
|
+ this.dialogVisible = true
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 编辑
|
|
|
+ handleEdit(row) {
|
|
|
+ this.initForm()
|
|
|
+ getLedger(row.id).then(response => {
|
|
|
+ this.form = { ...response.data }
|
|
|
+ this.dialogTitle = '编辑设备台账'
|
|
|
+ this.isView = false
|
|
|
+ this.dialogVisible = true
|
|
|
+ // 根据对象类型加载对应数据
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.form.objType === '3') {
|
|
|
+ if (this.facsGroupList.length === 0) {
|
|
|
+ this.loadFacsList()
|
|
|
+ }
|
|
|
+ } else if (this.form.objType === '2') {
|
|
|
+ this.loadDeviceList(this.form.deviceCategory || '')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 切换到编辑模式
|
|
|
+ switchToEdit() {
|
|
|
+ this.isView = false
|
|
|
+ this.dialogTitle = '编辑设备台账'
|
|
|
+ // 根据对象类型加载对应数据
|
|
|
+ if (this.form.objType === '3') {
|
|
|
+ if (this.facsGroupList.length === 0) {
|
|
|
+ this.loadFacsList()
|
|
|
+ }
|
|
|
+ } else if (this.form.objType === '2') {
|
|
|
+ this.loadDeviceList(this.form.deviceCategory || '')
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 提交表单
|
|
|
+ submitForm() {
|
|
|
+ this.$refs.ledgerForm.validate(valid => {
|
|
|
+ if (!valid) return
|
|
|
+
|
|
|
+ this.submitLoading = true
|
|
|
+ const submitData = { ...this.form }
|
|
|
+
|
|
|
+ // 处理objCode
|
|
|
+ if (Array.isArray(submitData.objCode)) {
|
|
|
+ submitData.objCode = submitData.objCode.join(',')
|
|
|
+ }
|
|
|
+
|
|
|
+ const request = submitData.id ? updateLedger(submitData) : addLedger(submitData)
|
|
|
+
|
|
|
+ request.then(() => {
|
|
|
+ this.$modal.msgSuccess(submitData.id ? '修改成功' : '新增成功')
|
|
|
+ this.dialogVisible = false
|
|
|
+ this.getList()
|
|
|
+ }).finally(() => {
|
|
|
+ this.submitLoading = false
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 删除
|
|
|
+ handleDelete(row) {
|
|
|
+ const ids = row.id || this.ids.join(',')
|
|
|
+ this.$modal.confirm(`确认删除该台账记录吗?`).then(() => {
|
|
|
+ return delLedger(ids)
|
|
|
+ }).then(() => {
|
|
|
+ this.getList()
|
|
|
+ this.$modal.msgSuccess('删除成功')
|
|
|
+ }).catch(() => {})
|
|
|
+ },
|
|
|
+
|
|
|
+ // 导出
|
|
|
+ handleExport() {
|
|
|
+ this.download('ems/device/ledger/export', {
|
|
|
+ ...this.queryParams
|
|
|
+ }, `设备台账_${new Date().getTime()}.xlsx`)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+// 变量定义
|
|
|
+$primary-color: #4f46e5;
|
|
|
+$primary-light: #818cf8;
|
|
|
+$bg-light: #f8fafc;
|
|
|
+$border-color: #e2e8f0;
|
|
|
+$text-primary: #1e293b;
|
|
|
+$text-secondary: #64748b;
|
|
|
+$shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
|
+$shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
|
+$radius: 12px;
|
|
|
+$radius-sm: 8px;
|
|
|
+
|
|
|
+.ledger-container {
|
|
|
+ display: flex;
|
|
|
+ gap: 20px;
|
|
|
+ padding: 20px;
|
|
|
+ min-height: calc(100vh - 84px);
|
|
|
+ background: linear-gradient(135deg, #f0f4ff 0%, #faf5ff 50%, #fff1f2 100%);
|
|
|
+}
|
|
|
+
|
|
|
+// 左侧边栏
|
|
|
+.sidebar {
|
|
|
+ width: 280px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: $radius;
|
|
|
+ box-shadow: $shadow-md;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .sidebar-header {
|
|
|
+ padding: 20px;
|
|
|
+ background: linear-gradient(135deg, $primary-color 0%, $primary-light 100%);
|
|
|
+
|
|
|
+ .sidebar-title {
|
|
|
+ margin: 0;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #fff;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+
|
|
|
+ i {
|
|
|
+ font-size: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .search-box {
|
|
|
+ padding: 16px;
|
|
|
+ border-bottom: 1px solid $border-color;
|
|
|
+
|
|
|
+ ::v-deep .el-input__inner {
|
|
|
+ border-radius: $radius-sm;
|
|
|
+ border-color: $border-color;
|
|
|
+
|
|
|
+ &:focus {
|
|
|
+ border-color: $primary-color;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .tree-wrapper {
|
|
|
+ padding: 12px;
|
|
|
+ max-height: calc(100vh - 300px);
|
|
|
+ overflow-y: auto;
|
|
|
+
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ width: 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
+ background: #cbd5e1;
|
|
|
+ border-radius: 3px;
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-tree {
|
|
|
+ background: transparent;
|
|
|
+
|
|
|
+ .el-tree-node__content {
|
|
|
+ height: 42px;
|
|
|
+ border-radius: $radius-sm;
|
|
|
+ margin-bottom: 4px;
|
|
|
+ transition: all 0.2s;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: $bg-light;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tree-node.is-current > .el-tree-node__content {
|
|
|
+ background: linear-gradient(135deg, rgba(79, 70, 229, 0.1) 0%, rgba(129, 140, 248, 0.1) 100%);
|
|
|
+ color: $primary-color;
|
|
|
+
|
|
|
+ .node-icon {
|
|
|
+ color: $primary-color;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .tree-node {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+
|
|
|
+ .node-icon {
|
|
|
+ font-size: 16px;
|
|
|
+ color: $text-secondary;
|
|
|
+ }
|
|
|
+
|
|
|
+ .node-label {
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 主内容区
|
|
|
+.main-content {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 16px;
|
|
|
+ min-width: 0;
|
|
|
+}
|
|
|
+
|
|
|
+// 标签页
|
|
|
+.content-header {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: $radius;
|
|
|
+ padding: 4px;
|
|
|
+ box-shadow: $shadow-sm;
|
|
|
+
|
|
|
+ .tabs-wrapper {
|
|
|
+ display: flex;
|
|
|
+ gap: 4px;
|
|
|
+
|
|
|
+ .tab-item {
|
|
|
+ flex: 1;
|
|
|
+ padding: 12px 20px;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: $text-secondary;
|
|
|
+ border-radius: $radius-sm;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 6px;
|
|
|
+
|
|
|
+ i {
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: $primary-color;
|
|
|
+ background: $bg-light;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ color: #fff;
|
|
|
+ background: linear-gradient(135deg, $primary-color 0%, $primary-light 100%);
|
|
|
+ box-shadow: 0 2px 8px rgba(79, 70, 229, 0.3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 筛选区
|
|
|
+.filter-section {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: $radius;
|
|
|
+ padding: 20px;
|
|
|
+ box-shadow: $shadow-sm;
|
|
|
+
|
|
|
+ .filter-form {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 12px;
|
|
|
+
|
|
|
+ ::v-deep .el-form-item {
|
|
|
+ margin-bottom: 0;
|
|
|
+ margin-right: 0;
|
|
|
+
|
|
|
+ .el-form-item__label {
|
|
|
+ color: $text-secondary;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-input__inner,
|
|
|
+ .el-date-editor {
|
|
|
+ border-radius: $radius-sm;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .filter-buttons {
|
|
|
+ margin-left: auto;
|
|
|
+
|
|
|
+ .el-button {
|
|
|
+ border-radius: $radius-sm;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 工具栏
|
|
|
+.toolbar {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .toolbar-left {
|
|
|
+ display: flex;
|
|
|
+ gap: 12px;
|
|
|
+
|
|
|
+ .el-button {
|
|
|
+ border-radius: $radius-sm;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .toolbar-right {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+
|
|
|
+ .el-button.is-circle {
|
|
|
+ border: none;
|
|
|
+ background: #fff;
|
|
|
+ box-shadow: $shadow-sm;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: $primary-color;
|
|
|
+ background: $bg-light;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 表格
|
|
|
+.table-wrapper {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: $radius;
|
|
|
+ overflow: hidden;
|
|
|
+ box-shadow: $shadow-sm;
|
|
|
+
|
|
|
+ ::v-deep .el-table {
|
|
|
+ th.el-table__cell {
|
|
|
+ border-bottom: 2px solid $border-color;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cell-area {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+
|
|
|
+ i {
|
|
|
+ color: $primary-color;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .cell-object {
|
|
|
+ .obj-name {
|
|
|
+ font-weight: 500;
|
|
|
+ color: $text-primary;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .maintain-title {
|
|
|
+ color: $text-primary;
|
|
|
+ }
|
|
|
+
|
|
|
+ .date-text {
|
|
|
+ color: $text-secondary;
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .action-buttons {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ .el-button {
|
|
|
+ padding: 4px 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .danger-btn {
|
|
|
+ color: #ef4444;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: #dc2626;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 分页
|
|
|
+.pagination-wrapper {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ padding: 16px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: $radius;
|
|
|
+ box-shadow: $shadow-sm;
|
|
|
+
|
|
|
+ ::v-deep .el-pagination {
|
|
|
+ .btn-prev,
|
|
|
+ .btn-next,
|
|
|
+ .el-pager li {
|
|
|
+ border-radius: $radius-sm;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-pager li.active {
|
|
|
+ background: $primary-color;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 对话框
|
|
|
+::v-deep .ledger-dialog {
|
|
|
+ border-radius: $radius;
|
|
|
+
|
|
|
+ .el-dialog__header {
|
|
|
+ padding: 20px 24px;
|
|
|
+ border-bottom: 1px solid $border-color;
|
|
|
+
|
|
|
+ .el-dialog__title {
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: $text-primary;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-dialog__body {
|
|
|
+ padding: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-dialog__footer {
|
|
|
+ padding: 16px 24px;
|
|
|
+ border-top: 1px solid $border-color;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.ledger-form {
|
|
|
+ ::v-deep .el-radio-button__inner {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .view-content {
|
|
|
+ padding: 12px;
|
|
|
+ background: $bg-light;
|
|
|
+ border-radius: $radius-sm;
|
|
|
+ min-height: 100px;
|
|
|
+ line-height: 1.6;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 下拉选项样式
|
|
|
+.select-option {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ .option-name {
|
|
|
+ font-weight: 500;
|
|
|
+ color: $text-primary;
|
|
|
+ }
|
|
|
+
|
|
|
+ .option-extra {
|
|
|
+ font-size: 12px;
|
|
|
+ color: $text-secondary;
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 设备选择行样式
|
|
|
+.device-select-row {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ .category-select {
|
|
|
+ width: 140px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .device-select {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 动画
|
|
|
+.slide-fade-enter-active {
|
|
|
+ transition: all 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.slide-fade-leave-active {
|
|
|
+ transition: all 0.2s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.slide-fade-enter,
|
|
|
+.slide-fade-leave-to {
|
|
|
+ transform: translateY(-10px);
|
|
|
+ opacity: 0;
|
|
|
+}
|
|
|
+
|
|
|
+// 响应式
|
|
|
+@media (max-width: 1200px) {
|
|
|
+ .ledger-container {
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .sidebar {
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ .tree-wrapper {
|
|
|
+ max-height: 300px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|