<template>
  <ContentWrap>
    <!-- 搜索工作栏 -->
    <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px">
      <el-form-item :label="t('DataCollection.Device.deviceCode')" prop="deviceCode">
        <el-input
          v-model="queryParams.deviceCode"
          :placeholder="t('DataCollection.Device.placeholderDeviceCode')"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px" />
      </el-form-item>
      <el-form-item :label="t('DataCollection.Device.deviceName')" prop="deviceName">
        <el-input
          v-model="queryParams.deviceName"
          :placeholder="t('DataCollection.Device.placeholderDeviceName')"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px" />
      </el-form-item>

      <!-- <el-form-item label="连接状态" prop="status">
        <el-select
          v-model="queryParams.status"
          placeholder="请选择状态"
          clearable
          class="!w-240px"
        >
          <el-option
            v-for="dict in getStrDictOptions(DICT_TYPE.IOT_GATEWAY_STATUS)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item> -->

      <!-- <el-form-item label="创建时间" prop="createTime">
        <el-date-picker
          v-model="queryParams.createTime"
          value-format="YYYY-MM-DD HH:mm:ss"
          type="daterange"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
          class="!w-240px"
        />
      </el-form-item> -->
      <el-form-item>
        <el-button @click="handleQuery">
          <Icon icon="ep:search" class="mr-5px" /> {{ t('DataCollection.Device.search') }}
        </el-button>
        <el-button @click="resetQuery">
          <Icon icon="ep:refresh" class="mr-5px" /> {{ t('DataCollection.Device.reset') }}
        </el-button>
        <el-button type="primary" plain @click="openForm('create')" v-hasPermi="['iot:device:create']">
          <Icon icon="ep:plus" class="mr-5px" /> {{ t('DataCollection.Device.create') }}
        </el-button>
        <el-button
          type="success" plain @click="handleExport" :loading="exportLoading"
          v-hasPermi="['iot:device:export']">
          <Icon icon="ep:download" class="mr-5px" /> {{ t('DataCollection.Device.export') }}
        </el-button>
        <el-button type="danger" plain @click="handleBatchDelete" v-hasPermi="['iot:device:delete']">
          <Icon icon="ep:delete" class="mr-5px" /> {{ t('DataCollection.Device.batchDelete') }}
        </el-button>
        <!-- 视图切换按钮 -->
        <el-button
          :type="currentView === 'grid' ? 'primary' : 'default'"
          :icon="currentView === 'grid' ? Menu : Grid"
          @click="toggleView"
          class="view-toggle-btn"
        >
          {{ currentView === 'grid' ? t('DataCollection.Device.gridView') : t('DataCollection.Device.sudoku') }}
        </el-button>
      </el-form-item>
    </el-form>
  </ContentWrap>

  <!-- 列表 GridView  Sudoku-->
  <ContentWrap>
    <div v-show="currentView === 'table'" class="simple-table-view">
    <el-table
      ref="tableRef" v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" row-key="id"
      @selection-change="handleSelectionChange" @row-click="handleShowAttribute">
      <el-table-column type="selection" width="55" reserve-selection />
      <el-table-column :label="t('DataCollection.Device.deviceCode')" align="left" prop="deviceCode" sortable/>
      <el-table-column :label="t('DataCollection.Device.deviceName')" align="left" prop="deviceName" sortable/>
      <el-table-column :label="t('DataCollection.Device.operatingStatus')" align="center" prop="operatingStatus" width="120px" sortable>
        <template #default="scope">
          <el-tag
            size="small"
            :type="getOperatingStatusType(scope.row.operatingStatus)"
          >
            {{ getOperatingStatusLabel(scope.row.operatingStatus) }}
          </el-tag>
        </template>
      </el-table-column>
      <!-- <el-table-column label="设备类型" align="left" prop="deviceType" width="150px" sortable> -->
      <!-- <template #default="scope">
          <dict-tag :type="DICT_TYPE.IOT_DEVICE_TYPE" :value="scope.row.deviceType" />
        </template>
      </el-table-column> -->
      <el-table-column :label="t('DataCollection.Device.protocol')" align="left" prop="protocol" width="120px">
        <template #default="scope">
          <dict-tag :type="DICT_TYPE.IOT_PROTOCOL" :value="scope.row.protocol" />
        </template>
      </el-table-column>
      <!-- <el-table-column :label="t('DataCollection.Device.status')" align="center" prop="status" width="120px" sortable>
        <template #default="scope">
          <dict-tag :type="DICT_TYPE.IOT_GATEWAY_STATUS" :value="scope.row.status" />
        </template>
      </el-table-column> -->
      <!-- <el-table-column label="读主题" align="center" prop="readTopic" />
      <el-table-column label="写主题" align="center" prop="writeTopic" />
      <el-table-column label="网关id" align="center" prop="gatewayId" /> -->
      <!--      <el-table-column label="设备品牌id" align="center" prop="deviceBrandId" />-->
      <!-- <el-table-column label="离线间隔" align="center" prop="offLineDuration" /> -->
      <!-- <el-table-column
        label="最后上线时间"
        align="center"
        prop="lastOnlineTime"
        :formatter="dateFormatter"
        width="180px"
       sortable /> -->
      <!-- <el-table-column label="备注" align="center" prop="remark" /> -->
      <!-- <el-table-column
        label="创建时间"
        align="center"
        prop="createTime"
        :formatter="dateFormatter"
        width="170px"
       sortable /> -->
      <el-table-column :label="t('DataCollection.Device.isEnable')" align="center" prop="isEnable" width="120px">
        <template #default="scope">
          <el-switch
            :model-value="isDeviceEnabled(scope.row)"
            @change="(val) => handleDeviceEnableChange(scope.row, val)"
          />
        </template>
      </el-table-column>
      <el-table-column
        :label="t('DataCollection.Device.collectionTime')"
        align="center"
        prop="collectionTime"
        width="180px"
        :formatter="dateFormatter"
        sortable
      />
      <el-table-column :label="t('DataCollection.Device.operate')" align="center" fixed="right" width="380px">
        <template #default="scope">
          <el-button link type="primary" @click.stop="handleShowAttribute(scope.row)">{{ t('DataCollection.Device.attributeModuleName') }}</el-button>
          <el-button
            link
            type="primary"
            @click="openForm('setting', scope.row.id)"
            v-hasPermi="['iot:device:update']"
          >
            {{ t('DataCollection.Device.settingDialogTitle') }}
          </el-button>
          <el-button
            link
            type="primary"
            @click="handleCopy(scope.row.id)"
            v-hasPermi="['iot:device:create']"
          >
            {{ t('action.copy') }}
          </el-button>
          <el-button
            link
            type="primary"
            @click.stop="handleEdit(scope.row)"
            v-hasPermi="['iot:device:update']"
          >
            {{ t('action.edit') }}
          </el-button>
          <el-button
            link
            type="danger"
            @click="handleDelete(scope.row.id)"
            v-hasPermi="['iot:device:delete']"
          >
            {{ t('action.delete') }}
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <Pagination
:total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
      @pagination="getList" />
    </div>

    <!-- 九宫格视图 -->
    <div v-show="currentView === 'grid'" class="simple-grid-view">
      <div v-if="!list || list.length === 0" class="empty-grid">
        <el-empty description="暂无设备数据"/>
      </div>

      <div v-else class="grid-container">
        <div
          v-for="(item, index) in list"
          :key="item.id || index"
          class="grid-card"
          @click="openDetailForm(item?.id,item?.deviceName)"
        >
          <!-- 设备状态指示 status-${item.deviceStatus} -->
          <div class="status-indicator" :class="getStatusText(item.operatingStatus)"></div>
          <!-- 设备基本信息 -->

          <div class="device-card">
            <div class="header">
              <div class="device-icon">
                <i>📊</i>
              </div>
              <div class="device-info">
                <div class="device-name">{{ item.deviceName }}</div>
                <div class="device-id">{{ item.deviceCode }}</div>
              </div>
              <div class="status-badge" :class="getStatusText(item.operatingStatus)">
                <span class="status-dot" :class="getStatusText(item.operatingStatus)"></span>
                {{ item.operatingStatus }}
              </div>
            </div>

            <div class="content">
              <div class="info-row">
                <div class="info-label">
                  <i>📡</i>
                  采集协议
                </div>
                <div class="info-value">
                  <dict-tag :type="DICT_TYPE.IOT_PROTOCOL" :value="item.protocol" />
                </div>
              </div>
              <div class="info-row">
                <div class="info-label">
                  <i>⏱️</i>
                  采集时间
                </div>
                <div class="info-value">
                  {{ item.collectionTime }}
                </div>
              </div>

              <div class="toggle-container"  @click.stop>
                <div class="toggle-label">
                  <i>🔘️</i>
                  是否启用
                </div>
                <el-switch
                  :model-value="isDeviceEnabled(item)"
                  @change="(val) => handleDeviceEnableChange(item, val)"
                />
<!--                <label class="toggle-switch">
                  <input type="checkbox" v-model="item.operatingStatus" @change.stop="enabledChange(item,item?.id)" />
                  <span class="slider"></span>
                </label>-->
              </div>
            </div>

            <div class="footer"  @click.stop>
              <div class="action-icons">
                <el-button class="action-btn btn-primary" @click.stop="openDetailForm(item?.id,item?.deviceName)" >
                  <i>📍</i>
                  {{ t('DataCollection.Device.attributeModuleName') }}
                </el-button>
                <el-button class="action-btn btn-success"  @click.stop="openForm('setting', item?.id)"  v-hasPermi="['iot:device:update']">
                  <i>⚙️</i>
                  {{ t('DataCollection.Device.settingDialogTitle') }}
                </el-button>

                <el-tooltip
                  :content="t('action.copy')"
                  placement="top"
                  effect="dark"
                >
                  <el-button
                    class="icon-btn"
                    link
                    type="primary"
                    @click="handleCopy(item?.id)"
                    v-hasPermi="['iot:device:create']"
                  >
                    📋
                  </el-button>
                </el-tooltip>
                <el-tooltip
                  :content="t('action.edit')"
                  placement="top"
                  effect="dark"
                >
                  <el-button
                    link
                    type="primary"
                    @click.stop="handleEdit(item)"
                    v-hasPermi="['iot:device:update']"
                  >
                    ✏️
                  </el-button>
                </el-tooltip>
                <el-tooltip
                  :content="t('DataCollection.Device.gridView')"
                  placement="top"
                  effect="dark"
                >
                <el-button class="icon-btn" @click.stop="changeTable">🏠</el-button>
                </el-tooltip>
              </div>
            </div>
          </div>
        </div>
      </div>
      <Pagination
        :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
        @pagination="getList"/>
    </div>


  </ContentWrap>

  <!-- 表单弹窗：添加/修改 -->
  <DeviceForm ref="formRef" @success="getList" />
  <!-- 子表的列表 -->
<!--  <ContentWrap v-if="ifShow">
    <template v-if="attributeDeviceId">
      <div class="mb-10px flex items-center justify-between text-sm text-gray-500">
        <div>
          {{ t('DataCollection.Device.currentDeviceLabel') }}<span class="font-medium text-gray-700">{{ attributeDeviceName || '-' }}</span>
        </div>
        <div>
          <el-button type="primary" link @click="handleShowDeviceAlarmHistory">
            {{ t('DataCollection.Device.alarmHistoryTitle') }}
          </el-button>
        </div>
      </div>
      <el-tabs v-model="deviceTabActive">
        <el-tab-pane :label="deviceAttributeTabLabel" name="deviceAttribute">
          <DeviceAttributeList :device-id="attributeDeviceId" />
        </el-tab-pane>
        <el-tab-pane :label="deviceRuleTabLabel" name="deviceRule">
          <el-form
            class="-mb-15px"
            :model="ruleQueryParams"
            ref="ruleQueryFormRef"
            :inline="true"
            label-width="120px"
          >
            <el-form-item :label="t('DataCollection.DeviceModel.ruleIdentifier')" prop="identifier">
              <el-input
                v-model="ruleQueryParams.identifier"
                :placeholder="t('DataCollection.DeviceModel.ruleSearchIdentifierPlaceholder')"
                clearable
                @keyup.enter="handleRuleQuery"
                class="!w-200px"
              />
            </el-form-item>
            <el-form-item :label="t('DataCollection.DeviceModel.ruleFieldName')" prop="fieldName">
              <el-input
                v-model="ruleQueryParams.fieldName"
                :placeholder="t('DataCollection.DeviceModel.ruleSearchFieldNamePlaceholder')"
                clearable
                @keyup.enter="handleRuleQuery"
                class="!w-200px"
              />
            </el-form-item>
            <el-form-item :label="t('DataCollection.DeviceModel.ruleDefaultValue')" prop="defaultValue">
              <el-input
                v-model="ruleQueryParams.defaultValue"
                :placeholder="t('DataCollection.DeviceModel.ruleSearchDefaultValuePlaceholder')"
                clearable
                @keyup.enter="handleRuleQuery"
                class="!w-200px"
              />
            </el-form-item>
            <el-form-item>
              <el-button @click="handleRuleQuery">
                <Icon icon="ep:search" class="mr-5px" /> {{ t('DataCollection.DeviceModel.ruleSearch') }}
              </el-button>
              <el-button @click="resetRuleQuery">
                <Icon icon="ep:refresh" class="mr-5px" /> {{ t('DataCollection.DeviceModel.ruleReset') }}
              </el-button>
            </el-form-item>
          </el-form>

          <div class="mb-10px flex justify-end gap-8px">
            <el-button type="primary" plain @click="openCreateCountRuleForm">
              新增产量
            </el-button>
            <el-button type="primary" @click="openCreateRuleForm">
              {{ t('DataCollection.DeviceModel.ruleCreateButton') }}
            </el-button>
          </div>

          <el-table
            v-loading="ruleLoading"
            :data="ruleList"
            :stripe="true"
            :show-overflow-tooltip="true"
            row-key="id"
          >
            <el-table-column :label="t('DataCollection.DeviceModel.ruleIdentifier')" align="center" prop="identifier" />
            <el-table-column :label="t('DataCollection.DeviceModel.ruleFieldName')" align="center" prop="fieldName"  sortable />
            <el-table-column :label="t('DataCollection.DeviceModel.ruleFieldRule')" align="center" prop="fieldRule" />
            <el-table-column :label="t('DataCollection.DeviceModel.ruleDefaultValue')" align="center" prop="defaultValue" />
            <el-table-column
              :label="t('DataCollection.DeviceModel.ruleCreateTime')"
              align="center"
              prop="createTime"
              :formatter="dateFormatter"
              width="180px"
              sortable
            />
        <el-table-column :label="t('DataCollection.DeviceModel.ruleOperate')" align="center" width="160px">
          <template #default="scope">
            <el-button link type="primary" @click="openRuleForm(scope.row)">
              {{ t('DataCollection.DeviceModel.ruleEditRuleButton') }}
            </el-button>
            <el-button
              v-if="scope.row.identifier === 'ALARM' || scope.row.identifier === 'COUNT'"
              link
              type="danger"
              @click="handleRuleDelete(scope.row.id)"
            >
              {{ t('DataCollection.DeviceModel.ruleDeleteRuleButton') }}
            </el-button>
          </template>
        </el-table-column>
          </el-table>
          <Pagination
            :total="ruleTotal"
            v-model:page="ruleQueryParams.pageNo"
            v-model:limit="ruleQueryParams.pageSize"
            @pagination="getRuleList"
          />

          <el-dialog v-model="ruleDialogVisible" :title="t('DataCollection.DeviceModel.ruleDialogTitle')" width="880px" draggable>
            <el-form :model="ruleForm" ref="ruleFormRef" label-width="120px">
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogIdentifier')">
                <el-input v-model="ruleForm.identifier" disabled />
              </el-form-item>
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogFieldName')">
                <el-input v-model="ruleForm.fieldName" disabled />
              </el-form-item>
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogDefaultValue')">
                <el-input v-model="ruleForm.defaultValue" disabled />
              </el-form-item>
              <el-form-item
                v-if="(ruleForm.identifier || '').toString().toUpperCase() === 'ALARM'"
                :label="t('DataCollection.DeviceModel.ruleDialogAlarmLevel')"
              >
                <el-select
                  v-model="ruleForm.alarmLevel"
                  :placeholder="t('DataCollection.DeviceModel.ruleDialogAlarmLevelPlaceholder')"
                >
                  <el-option
                    v-for="dict in getStrDictOptions(DICT_TYPE.IOT_ALARM_REGISTRATION)"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  />
                </el-select>
              </el-form-item>

              <div class="flex flex-col w-full">
                <div class="border border-gray-200 dark:border-gray-600 rounded-md py-12px">
                  <el-form-item
                    v-if="!isCountIdentifier"
                    :label="t('DataCollection.DeviceModel.ruleDialogFieldRule')"
                  >
                    <el-select
                      v-model="ruleForm.fieldRule"
                      :placeholder="t('DataCollection.DeviceModel.ruleDialogFieldRulePlaceholder')"
                      class="!w-240px"
                      :disabled="!currentRuleOptions.length"
                    >
                      <el-option
                        v-for="item in currentRuleOptions"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                        :disabled="isRuleDisabled(item.value, ruleForm.fieldRule)"
                      />
                    </el-select>
                  </el-form-item>
                  <el-form-item :label="isCountIdentifier ? '四则运算规则' : t('DataCollection.DeviceModel.ruleDialogRule')">
                    <div v-if="isCountIdentifier" class="w-full flex flex-col gap-8px">
                      <div
                        v-for="(item, index) in countArithmeticRules"
                        :key="index"
                        class="flex items-center gap-8px"
                      >
                        <el-select
                          v-model="item.ruleAttributeId"
                          :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleAttributePlaceholder')"
                          class="!w-240px"
                          clearable
                        >
                          <el-option
                            v-for="attr in ruleAttributeOptions"
                            :key="attr.id"
                            :label="attr.attributeName || attr.attributeCode"
                            :value="attr.id"
                          />
                        </el-select>
                        <el-select
                          v-model="item.ruleOperator"
                          :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleOperatorPlaceholder')"
                          class="!w-160px"
                          clearable
                        >
                          <el-option
                            v-for="operator in currentRuleOperatorOptions"
                            :key="operator.value"
                            :label="operator.label"
                            :value="operator.value"
                          />
                        </el-select>
                        <el-input
                          v-model="item.ruleValue"
                          :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleValuePlaceholder')"
                          class="!w-200px"
                          clearable
                        />
                        <template v-if="index < countArithmeticRules.length - 1">
                          <el-select
                            v-model="countArithmeticRules[index].bigOperator"
                            :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleOperatorPlaceholder')"
                            class="!w-110px"
                            clearable
                          >
                            <el-option
                              v-for="operator in countOperatorOptions"
                              :key="operator.value"
                              :label="operator.label"
                              :value="operator.value"
                            />
                          </el-select>
                        </template>
                        <template v-else>
                          <div class="flex items-center gap-4px">
                            <el-button link type="primary" @click="handleAddCountArithmeticRule">
                              <Icon icon="ep:plus" />
                            </el-button>
                            <el-button
                              link
                              type="danger"
                              :disabled="countArithmeticRules.length <= 1"
                              @click="handleRemoveCountArithmeticRule(index)"
                            >
                              <Icon icon="ep:minus" />
                            </el-button>
                          </div>
                        </template>
                      </div>
                      <div class="text-12px text-[#909399] leading-20px">按“四则运算规则”添加顺序从上到下依次计算，不按乘除优先。</div>
                    </div>
                    <div v-else class="flex items-center gap-8px">
                      <el-select
                        v-model="ruleForm.ruleAttributeId"
                        :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleAttributePlaceholder')"
                        class="!w-240px"
                        clearable
                      >
                        <el-option
                          v-for="item in ruleAttributeOptions"
                          :key="item.id"
                          :label="item.attributeName || item.attributeCode"
                          :value="item.id"
                        />
                      </el-select>
                      <el-select
                        v-model="ruleForm.ruleOperator"
                        :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleOperatorPlaceholder')"
                        class="!w-160px"
                        clearable
                      >
                        <el-option
                          v-for="item in currentRuleOperatorOptions"
                          :key="item.value"
                          :label="item.label"
                          :value="item.value"
                        />
                      </el-select>
                      <el-input
                        v-if="ruleForm.ruleOperator !== 'TRUE' && ruleForm.ruleOperator !== 'FALSE'"
                        v-model="ruleForm.ruleValue"
                        :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleValuePlaceholder')"
                        class="!w-200px"
                        clearable
                      />
                    </div>
                  </el-form-item>
                </div>

                <template v-if="isRunningIdentifier">
                  <div
                    v-for="(item, index) in extraPointRules"
                    :key="index"
                    class="border border-gray-200 dark:border-gray-600 rounded-md px-16px py-12px"
                  >
                    <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogFieldRule')">
                      <el-select
                        v-model="item.rule"
                        :placeholder="t('DataCollection.DeviceModel.ruleDialogFieldRulePlaceholder')"
                        class="!w-240px"
                      >
                        <el-option
                          v-for="opt in currentRuleOptions"
                          :key="opt.value"
                          :label="opt.label"
                          :value="opt.value"
                          :disabled="isRuleDisabled(opt.value, item.rule)"
                        />
                      </el-select>
                    </el-form-item>
                    <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogRule')">
                      <div class="flex items-center gap-8px">
                        <el-select
                          v-model="item.id"
                          :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleAttributePlaceholder')"
                          class="!w-240px"
                        >
                          <el-option
                            v-for="attr in ruleAttributeOptions"
                            :key="attr.id"
                            :label="attr.attributeName || attr.attributeCode"
                            :value="attr.id"
                          />
                        </el-select>
                        <el-select
                          v-model="item.operator"
                          :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleOperatorPlaceholder')"
                          class="!w-160px"
                        >
                          <el-option
                            v-for="opt in ruleOperatorOptions"
                            :key="opt.value"
                            :label="opt.label"
                            :value="opt.value"
                          />
                        </el-select>
                        <el-input
                          v-if="isCountIdentifier || (item.operator !== 'TRUE' && item.operator !== 'FALSE')"
                          v-model="item.operatorRule"
                          :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleValuePlaceholder')"
                          class="!w-200px"
                        />
                        <el-button type="danger" link @click="handleRemovePointRule(index)">
                          {{ t('DataCollection.DeviceModel.ruleDeleteRuleButton') }}
                        </el-button>
                      </div>
                    </el-form-item>
                  </div>
                </template>

                <el-form-item v-if="isRunningIdentifier" label=" ">
                  <el-button type="primary" link @click="handleAddPointRule">
                    + {{ t('DataCollection.DeviceModel.ruleCreateButton') }}
                  </el-button>
                </el-form-item>
              </div>
            </el-form>
            <template #footer>
              <span class="dialog-footer">
                <el-button @click="ruleDialogVisible = false">{{ t('DataCollection.DeviceModel.dialogCancel') }}</el-button>
                <el-button type="primary" :loading="ruleFormLoading" @click="handleRuleSubmit">{{ t('DataCollection.DeviceModel.dialogOk') }}</el-button>
              </span>
            </template>
          </el-dialog>

          <el-dialog v-model="createRuleDialogVisible" :title="createRuleDialogTitle" width="520px" draggable>
            <el-form :model="createRuleForm" ref="createRuleFormRef" label-width="120px">
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogIdentifier')">
                <el-input v-model="createRuleForm.identifier" disabled />
              </el-form-item>
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogFieldName')">
                <el-input
                  v-model="createRuleForm.fieldName"
                  :placeholder="t('DataCollection.DeviceModel.ruleSearchFieldNamePlaceholder')"
                  :disabled="isCreateCountRule"
                />
              </el-form-item>
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogDefaultValue')">
                <el-input v-model="createRuleForm.defaultValue" disabled />
              </el-form-item>
              <el-form-item v-if="!isCreateCountRule" :label="t('DataCollection.DeviceModel.ruleDialogAlarmLevel')">
                <el-select
                  v-model="createRuleForm.alarmLevel"
                  :placeholder="t('DataCollection.DeviceModel.ruleDialogAlarmLevelPlaceholder')"
                >
                  <el-option
                    v-for="dict in getStrDictOptions(DICT_TYPE.IOT_ALARM_REGISTRATION)"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  />
                </el-select>
              </el-form-item>
            </el-form>
            <template #footer>
              <span class="dialog-footer">
                <el-button @click="createRuleDialogVisible = false">{{ t('DataCollection.DeviceModel.dialogCancel') }}</el-button>
                <el-button type="primary" :loading="createRuleFormLoading" @click="handleCreateRuleSubmit">
                  {{ t('DataCollection.DeviceModel.dialogOk') }}
                </el-button>
              </span>
            </template>
          </el-dialog>
        </el-tab-pane>
      </el-tabs>
    </template>
    <el-empty v-else :description="t('DataCollection.Device.emptyDescription')" />
  </ContentWrap>-->

  <Dialog :title="t('DataCollection.Device.alarmHistoryTitle')" v-model="deviceAlarmDialogVisible" width="1200px">
    <el-form
      class="-mb-15px"
      :model="deviceAlarmQueryParams"
      ref="deviceAlarmQueryFormRef"
      :inline="true"
      label-width="80px"
    >
      <el-form-item :label="t('DataCollection.Device.alarmRuleName')" prop="ruleId">
        <el-select
          v-model="deviceAlarmQueryParams.ruleId"
          :loading="deviceAlarmRuleLoading"
          clearable
          filterable
          class="!w-220px"
          :placeholder="t('DataCollection.DeviceModel.ruleSearchFieldNamePlaceholder')"
        >
          <el-option
            v-for="item in deviceAlarmRuleOptions"
            :key="item.id"
            :label="item.fieldName || item.ruleName || item.name"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item :label="t('DataCollection.Device.alarmPointName')" prop="modelId">
        <el-select
          v-model="deviceAlarmQueryParams.modelId"
          :loading="deviceAlarmPointLoading"
          clearable
          filterable
          class="!w-220px"
          :placeholder="t('DataCollection.Device.placeholderAttributeName')"
        >
          <el-option
            v-for="item in deviceAlarmPointOptions"
            :key="item.id"
            :label="item.attributeName || item.attributeCode || item.name"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item :label="t('DataCollection.Device.alarmTime')" prop="createTime">
        <el-date-picker
          v-model="deviceAlarmQueryParams.createTime"
          value-format="YYYY-MM-DD HH:mm:ss"
          type="daterange"
          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
          :start-placeholder="t('DataCollection.HistoryData.dialogCollectionTimeStartPlaceholder')"
          :end-placeholder="t('DataCollection.HistoryData.dialogCollectionTimeEndPlaceholder')"
          class="!w-260px"
        />
      </el-form-item>
      <el-form-item>
        <el-button @click="handleDeviceAlarmQuery">
          <Icon icon="ep:search" class="mr-5px" />
          {{ t('DataCollection.Device.search') }}
        </el-button>
        <el-button @click="resetDeviceAlarmQuery">
          <Icon icon="ep:refresh" class="mr-5px" />
          {{ t('DataCollection.Device.reset') }}
        </el-button>
      </el-form-item>
    </el-form>

    <el-table
      :data="deviceAlarmList"
      v-loading="deviceAlarmLoading"
      :stripe="true"
      :show-overflow-tooltip="true"
      :max-height="700"
      class="mt-10px"
    >
      <el-table-column :label="t('DataCollection.Device.alarmRuleName')" align="center" prop="ruleName"  sortable />
      <el-table-column :label="t('DataCollection.Device.alarmPointName')" align="center" prop="modelName"  sortable />
      <el-table-column :label="t('DataCollection.Device.alarmPointValue')" align="center" prop="addressValue" />
      <el-table-column :label="t('DataCollection.Device.alarmLevel')" align="center" prop="alarmLevel">
        <template #default="scope">
          <dict-tag :type="DICT_TYPE.IOT_ALARM_REGISTRATION" :value="scope.row.alarmLevel" />
        </template>
      </el-table-column>
      <el-table-column
        :label="t('DataCollection.Device.alarmTime')"
        align="center"
        prop="createTime"
        :formatter="dateFormatter"
        width="180px"
       sortable />
    </el-table>
    <div class="mt-10px pb-10px flex justify-end">
      <Pagination
        :total="deviceAlarmTotal"
        v-model:page="deviceAlarmQueryParams.pageNo"
        v-model:limit="deviceAlarmQueryParams.pageSize"
        @pagination="getDeviceAlarmList"
      />
    </div>
  </Dialog>

  <!-- 表单弹窗：弹出设备属性 -->
  <DetailForm  ref="detailFormRef"  />
</template>

<script setup lang="ts">
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import request from '@/config/axios'
import { DeviceApi, DeviceConnectParams, DeviceVO } from '@/api/iot/device'
import DeviceForm from './DeviceForm.vue'
import DeviceAttributeList from './components/DeviceAttributeList.vue'
import {
  Refresh,
  Grid,
  Menu,
  Search,
  Location
} from '@element-plus/icons-vue'
import {useRouter} from "vue-router";
import DetailForm from "@/views/iot/device/detailForm.vue";
import {ProductUnitApi, ProductUnitVO} from "@/api/erp/product/unit";
const ifShow =ref(true)
const currentView = ref('table') // 'table' 或 'grid'
// 路由
const router = useRouter()
// 查看详情
const handleView = (row) => {
  router.push({
    path: '/equipment/detail',
    query: {id: row.id}
  })
}
/** 设备类型 列表 */
//defineOptions({name: 'DeviceLedger'})
const getEquipmentColor = (type) => {
  const colorMap = {
    'production': '#409eff',
    'inspection': '#67c23a',
    'packaging': '#e6a23c',
    'transport': '#f56c6c',
    'other': '#909399'
  }
  return colorMap[type] || '#409eff'
}

const getEquipmentIcon = (type) => {
  const iconMap = {
    'production': 'Monitor',
    'inspection': 'Search',
    'packaging': 'Box',
    'transport': 'Truck',
    'other': 'Tools'
  }
  return iconMap[type] || 'Tools'
}

// 工具函数
const getStatusTag = (status) => {
  const tagMap = {
    '运行': 'success',//running
    '待机中': 'info',//standby
    '故障中': 'danger',//fault
    '报警中': 'warning',//maintenance
    '离线': 'info'//stopped
  }
  return tagMap[status] || 'info'
}

const getStatusText = (status) => {
  const textMap = {
    '运行': 'status-running',
    '待机中': 'status-standby',
    '故障中': 'status-fault',
    '报警中': 'status-maintenance',
    '离线': 'status-stopped'
  }
  return textMap[status] || '未知'
}
// 切换视图
const toggleView = () => {

  currentView.value = currentView.value === 'table' ? 'grid' : 'table'
  ifShow.value=currentView.value === 'table' ? true : false;
  // 保存视图偏好
  localStorage.setItem('equipment-view', currentView.value)
}
// 切回表格
const changeTable = () => {
  currentView.value = 'table'
  ifShow.value=true;
  // 保存视图偏好
  localStorage.setItem('equipment-view', currentView.value)
}

/** 物联设备 列表 */
defineOptions({ name: 'Device' })

const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化

const tableRef = ref()

const loading = ref(true) // 列表的加载中
const showDetailForm =ref(true)
const list = ref<DeviceVO[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  deviceCode: undefined,
  deviceName: undefined,
  deviceType: undefined,
  status: undefined,
  readTopic: undefined,
  writeTopic: undefined,
  gatewayId: undefined,
  deviceBrandId: undefined,
  offLineDuration: undefined,
  lastOnlineTime: [],
  remark: undefined,
  isEnable: undefined,
  createTime: []
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中

const getOperatingStatusLabel = (value: string | number | undefined) => {
  const text = String(value ?? '').trim()
  if (!text) return '离线'
  return text
}

const getOperatingStatusType = (value: string | number | undefined) => {
  const text = String(value ?? '').trim()
  if (!text) return 'info'
  if (text === '运行') return 'success'
  if (text === '待机中') return 'info'
  if (text === '故障中') return 'danger'
  if (text === '报警中') return 'warning'
  return 'info'
}

const isDeviceEnabled = (row: DeviceVO) => {
  const value = (row as any)?.isEnable
  if (typeof value === 'boolean') return value
  const text = String(value ?? '').toLowerCase().trim()
  if (!text) return false
  if (text === 'true' || text === '1' || text === 'yes') return true
  return false
}

const handleDeviceEnableChange = async (row: DeviceVO, value: boolean) => {
  if (!row.id) return
  const oldValue = (row as any).isEnable
  ;(row as any).isEnable = value
  try {
    await DeviceApi.updateDeviceEnabled(row.id, value ? 'true' : 'false')
    const name = (row as any).deviceName ?? (row as any).deviceCode ?? ''
    const suffix = value ? '已启用' : '已停用'
    if (name) {
      message.success(`${name}${suffix}`)
    } else {
      message.success(suffix)
    }
  } catch {
    ;(row as any).isEnable = oldValue
    message.error(t('common.updateFail'))
  }
}

const selectedIds = ref<number[]>([])
const handleSelectionChange = (rows: any[]) => {
  selectedIds.value = rows?.map((row) => row.id).filter((id) => id !== undefined) ?? []
}

/** 查询列表 */
const getList = async (showLoading = true) => {
  if (showLoading) {
    loading.value = true
  }
  try {
    const data = await DeviceApi.getDevicePage(queryParams)
    list.value = data.list
    total.value = data.total
  } finally {
    if (showLoading) {
      loading.value = false
    }
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
  formRef.value.open(type, id)
}
/** 设备属性弹出框 */
const detailFormRef = ref()
const openDetailForm = (id?: number,deviceName?:string) => {
  attributeDeviceId.value = undefined
  attributeDeviceName.value = ''
  detailFormRef.value.open(id,deviceName)
  //formRef.value.open(id,deviceName)
}

const enabledChange = (row: DeviceVO, value: boolean) => {
  showDetailForm.value=false
  if (!row.id) return
  const oldValue = (row as any).isEnable
  ;(row as any).isEnable = value
  try {
    DeviceApi.updateDeviceEnabled(row.id, value ? 'true' : 'false')
    const name = (row as any).deviceName ?? (row as any).deviceCode ?? ''
    const suffix = value ? '已启用' : '已停用'
    if (name) {
      message.success(`${name}${suffix}`)
    } else {
      message.success(suffix)
    }
  } catch {
    ;(row as any).is
  }
}

/** 删除按钮操作 */
const buildIdsParam = (ids: number | number[]) => {
  return Array.isArray(ids) ? ids.join(',') : String(ids)
}

const handleDelete = async (ids: number | number[]) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    const idsParam = buildIdsParam(ids)
    await DeviceApi.deleteDevice(idsParam)
    message.success(t('common.delSuccess'))
    selectedIds.value = []
    tableRef.value?.clearSelection?.()


    if (attributeDeviceId.value && idsParam.split(',').includes(String(attributeDeviceId.value))) {
      attributeDeviceId.value = undefined
      attributeDeviceName.value = ''
    }
    // 刷新列表
    await getList()
  } catch { }
}

const handleBatchDelete = async () => {
  if (!selectedIds.value.length) {
    message.error(t('common.delNoData'))
    return
  }
  await handleDelete(selectedIds.value)
}

const handleCopy = async (id: number) => {
  // 二次确认
  await message.confirm('是否复制设备?')
  try {
    await DeviceApi.copyDevice(id)
    message.success(t('common.copySuccess'))
    await getList()
  } catch { }
}

/** 导出按钮操作 */
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const params: any = {
      ...queryParams,
      ids: selectedIds.value.length ? selectedIds.value.join(',') : undefined
    }
    const data = await DeviceApi.exportDevice(params)
    download.excel(data, t('DataCollection.Device.exportFilename'))
  } catch {
  } finally {
    exportLoading.value = false
  }
}

interface DevicePointRuleVO {
  id: number
  identifier: string
  fieldName: string
  fieldRule: string
  defaultValue: string
  deviceId: number
  createTime?: string | number | Date
  ruleAttributeId?: number
  ruleOperator?: string
  ruleValue?: string | number
}

const attributeDeviceId = ref<number | undefined>(undefined)
const attributeDeviceName = ref('')

const deviceTabActive = ref('deviceAttribute')

const deviceAttributeTabLabel = computed(() => {
  return t('DataCollection.Device.deviceAttributeTabLabel')
})

const deviceRuleTabLabel = computed(() => {
  return t('DataCollection.Device.deviceRuleTabLabel')
})

const handleShowAttribute = (row: any) => {
  attributeDeviceId.value = row?.id
  attributeDeviceName.value = row?.deviceName ?? ''
  router.push({
    path: '/iot/pointManagement',
        query: {
          id: row?.id,
          name: row?.deviceName
        }
  });

}

const ruleLoading = ref(false)
const ruleList = ref<DevicePointRuleVO[]>([])
const ruleTotal = ref(0)
const ruleQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  identifier: undefined as string | undefined,
  fieldName: undefined as string | undefined,
  fieldRule: undefined as string | undefined,
  defaultValue: undefined as string | undefined,
  alarmLevel: undefined as string | undefined,
  deviceId: undefined as number | undefined,
})
const ruleQueryFormRef = ref()

const ruleAttributeOptions = ref<any[]>([])

const getRuleList = async () => {
  if (!attributeDeviceId.value) return
  ruleLoading.value = true
  try {
    const params = {
      ...ruleQueryParams,
      deviceId: attributeDeviceId.value,
    }
    const data = await request.get({ url: '/iot/device-point-rules/page', params })
    const listData = Array.isArray((data as any)?.list) ? (data as any).list : (Array.isArray(data) ? data : [])
    const totalData = (data as any)?.total ?? listData.length
    ruleList.value = listData as DevicePointRuleVO[]
    ruleTotal.value = totalData
  } finally {
    ruleLoading.value = false
  }
}

const handleRuleQuery = () => {
  if (!attributeDeviceId.value) return
  ruleQueryParams.pageNo = 1
  getRuleList()
}

const resetRuleQuery = () => {
  if (!attributeDeviceId.value) return
  ruleQueryFormRef.value?.resetFields?.()
  handleRuleQuery()
}

const loadRuleAttributeOptions = async (deviceId: number) => {
  try {
    const res = await request.get({ url: '/iot/device-contact-model/list', params: { id: deviceId } })
    const data = Array.isArray(res) ? res : (res as any)?.list ?? []
    ruleAttributeOptions.value = data as any[]
  } catch {
    ruleAttributeOptions.value = []
  }
}

watch(
  () => attributeDeviceId.value,
  async (val) => {
    ruleQueryParams.deviceId = val ?? undefined
    if (!val) {
      ruleList.value = []
      ruleTotal.value = 0
      ruleAttributeOptions.value = []
      return
    }
    ruleQueryParams.pageNo = 1
    await getRuleList()
  }
)

const ruleDialogVisible = ref(false)
const ruleFormLoading = ref(false)
const ruleFormRef = ref()
const ruleForm = reactive<Partial<DevicePointRuleVO>>({
  id: undefined,
  identifier: '',
  fieldName: '',
  fieldRule: '',
  defaultValue: '',
  deviceId: undefined,
  ruleAttributeId: undefined,
  ruleOperator: undefined,
  ruleValue: undefined,
   alarmLevel: '',
})
type CountArithmeticRule = {
  ruleAttributeId?: number
  ruleOperator?: string
  ruleValue?: string | number
  bigOperator?: string
}
const createEmptyCountArithmeticRule = (): CountArithmeticRule => ({
  ruleAttributeId: undefined,
  ruleOperator: undefined,
  ruleValue: undefined,
})
const countArithmeticRules = ref<CountArithmeticRule[]>([createEmptyCountArithmeticRule()])

const extraPointRules = ref<
  Array<{
    id?: number
    rule?: string
    operator?: string
    operatorRule?: string | number
  }>
>([])

const runningRuleOptions = [
  { value: '1', label: '运行' },
  { value: '2', label: '待机中（不运行、没故障）' },
  { value: '3', label: '故障中（故障且待机）' },
  // { value: '4', label: '报警中（故障且运行）' },
]

const alarmRuleOptions = [{ value: '5', label: '报警' }]
const countOperatorOptions = [
  { value: '+', label: '+' },
  { value: '-', label: '-' },
  { value: '*', label: '*' },
  { value: '/', label: '/' },
]

const currentRuleOptions = computed(() => {
  const id = (ruleForm.identifier || '').toString().toUpperCase()
  if (id === 'RUNNING') return runningRuleOptions
  if (id === 'ALARM') return alarmRuleOptions
  return []
})

const isRuleDisabled = (value: string, selfRule?: string | number) => {
  if (!value) return false
  const v = String(value)
  const self = selfRule != null ? String(selfRule) : undefined
  if (self === v) return false
  if (ruleForm.fieldRule && String(ruleForm.fieldRule) === v && self !== v) return true
  if (
    extraPointRules.value.some(
      (item) => item.rule != null && String(item.rule) === v && String(item.rule) !== self
    )
  ) {
    return true
  }
  return false
}

const ruleOperatorOptions = computed(() => getStrDictOptions('czsb_rules_conditions'))
const isCountIdentifier = computed(() => {
  return (ruleForm.identifier || '').toString().toUpperCase() === 'COUNT'
})
const currentRuleOperatorOptions = computed(() => {
  if (isCountIdentifier.value) return countOperatorOptions
  return ruleOperatorOptions.value
})

const isRunningIdentifier = computed(() => {
  return (ruleForm.identifier || '').toString().toUpperCase() === 'RUNNING'
})
const resolveRuleAttributeIdByCode = (code: any) => {
  if (code == null) return undefined
  const targetCode = String(code).trim().toUpperCase()
  const target = ruleAttributeOptions.value.find(
    (item) => String(item?.attributeCode ?? '').trim().toUpperCase() === targetCode
  )
  return target?.id
}
const toCountRuleValue = (value: any) => {
  const text = String(value ?? '').trim()
  if (!text) return ''
  if (/^-?\d+(\.\d+)?$/.test(text)) {
    return Number(text)
  }
  return text
}
const parseAlarmRunningFieldRule = (fieldRule: any) => {
  if (!fieldRule) return [] as any[]
  if (Array.isArray(fieldRule)) return fieldRule
  if (typeof fieldRule === 'string') {
    try {
      const parsed = JSON.parse(fieldRule)
      return Array.isArray(parsed) ? parsed : []
    } catch {
      return []
    }
  }
  return []
}
const buildAlarmRunningFieldRule = () => {
  const list: Array<{
    code: string
    operator: string
    operatorRule: string | number
    rule: string
  }> = []
  if (ruleForm.ruleAttributeId && ruleForm.ruleOperator) {
    const attr = ruleAttributeOptions.value.find((item) => item.id === ruleForm.ruleAttributeId)
    if (attr?.attributeCode) {
      list.push({
        code: attr.attributeCode,
        operator: String(ruleForm.ruleOperator),
        operatorRule: (ruleForm.ruleValue as any) ?? '',
        rule: String(ruleForm.fieldRule ?? ''),
      })
    }
  }
  extraPointRules.value.forEach((item) => {
    if (!item.id || !item.operator) return
    const attr = ruleAttributeOptions.value.find((opt) => opt.id === item.id)
    if (!attr?.attributeCode) return
    list.push({
      code: attr.attributeCode,
      operator: String(item.operator),
      operatorRule: (item.operatorRule as any) ?? '',
      rule: String(item.rule ?? ruleForm.fieldRule ?? ''),
    })
  })
  return JSON.stringify(list)
}
const buildCountFieldRule = (rules: CountArithmeticRule[]) => {
  const validRules = rules.filter((item) => {
    return item.ruleAttributeId && item.ruleOperator && String(item.ruleValue ?? '').trim() !== ''
  })
  if (!validRules.length) return ''
  const list = validRules.map((item, index) => {
    const attr = ruleAttributeOptions.value.find((opt) => opt.id === item.ruleAttributeId)
    if (!attr?.attributeCode) return undefined
    const row: any = {
      code: attr.attributeCode,
      operator: String(item.ruleOperator),
      value: toCountRuleValue(item.ruleValue),
    }
    if (index < validRules.length - 1 && item.bigOperator) {
      row.bigOperator = String(item.bigOperator)
    }
    return row
  }).filter(Boolean)
  if (!list.length) return ''
  return JSON.stringify(list)
}
const parseCountFieldRule = (fieldRule: any): CountArithmeticRule[] => {
  if (!fieldRule) return []
  const parsed = (() => {
    if (typeof fieldRule !== 'string') return fieldRule
    try {
      return JSON.parse(fieldRule)
    } catch {
      return undefined
    }
  })() as any
  if (Array.isArray(parsed)) {
    return parsed
      .map((item: any) => {
        const pointId = resolveRuleAttributeIdByCode(item?.code) ?? item?.pointId
        return {
          ruleAttributeId: pointId != null ? Number(pointId) : undefined,
          ruleOperator: item?.operator,
          ruleValue: item?.value ?? item?.operatorRule,
          bigOperator: item?.bigOperator,
        } as CountArithmeticRule
      })
      .filter((item) => item.ruleAttributeId || item.ruleOperator || item.ruleValue != null || item.bigOperator)
  }
  const root = parsed?.expr ?? parsed
  if (!root || typeof root !== 'object') return []
  const rows: CountArithmeticRule[] = []
  const walk = (node: any) => {
    if (!node || typeof node !== 'object' || !node.op) return
    if (node.left && typeof node.left === 'object' && node.left.op) {
      walk(node.left)
    }
    const attrId = resolveRuleAttributeIdByCode(node?.left?.field)
    const rightValue =
      node?.right?.field != null
        ? String(node.right.field)
        : node?.right?.value != null
          ? node.right.value
          : undefined
    rows.push({
      ruleAttributeId: attrId,
      ruleOperator: node.op,
      ruleValue: rightValue,
    })
  }
  walk(root)
  return rows.filter((item) => item.ruleOperator || item.ruleAttributeId || item.ruleValue != null)
}
const handleAddCountArithmeticRule = () => {
  countArithmeticRules.value.push(createEmptyCountArithmeticRule())
}
const handleRemoveCountArithmeticRule = (index: number) => {
  if (countArithmeticRules.value.length <= 1) return
  if (index < 0 || index >= countArithmeticRules.value.length) return
  countArithmeticRules.value.splice(index, 1)
  const list = countArithmeticRules.value
  if (list.length > 0) {
    list[list.length - 1].bigOperator = undefined
  }
}

const openRuleForm = async (row: DevicePointRuleVO & { pointRulesVOList?: any[] }) => {
  const deviceId = row.deviceId || attributeDeviceId.value
  if (!deviceId) {
    message.error(t('DataCollection.Device.messageDeviceInfoMissingForRules'))
    return
  }

  await loadRuleAttributeOptions(deviceId)

  ruleForm.id = row.id
  ruleForm.identifier = row.identifier
  ruleForm.fieldName = row.fieldName
  ruleForm.defaultValue = row.defaultValue
  ruleForm.deviceId = row.deviceId
  ruleForm.alarmLevel = (row as any).alarmLevel
  countArithmeticRules.value = [createEmptyCountArithmeticRule()]

  extraPointRules.value = []

  const list = Array.isArray(row.pointRulesVOList) ? row.pointRulesVOList : []
  const parsedAlarmRunningList = parseAlarmRunningFieldRule(row.fieldRule)
  const identifier = (row.identifier || '').toString().toUpperCase()

  if (identifier !== 'COUNT' && parsedAlarmRunningList.length) {
    const first = parsedAlarmRunningList[0] as any
    ruleForm.fieldRule = first?.rule ?? ''
    ruleForm.ruleAttributeId = resolveRuleAttributeIdByCode(first?.code) as any
    ruleForm.ruleOperator = first?.operator as any
    ruleForm.ruleValue = first?.operatorRule as any
    extraPointRules.value = parsedAlarmRunningList.slice(1).map((item: any) => ({
      id: resolveRuleAttributeIdByCode(item?.code),
      rule: item?.rule,
      operator: item?.operator,
      operatorRule: item?.operatorRule,
    }))
  } else if (list.length) {
    const first = list[0] as any
    const firstRule = first.rule ?? row.fieldRule
    const firstAttrId = (() => {
      if (first && first.code != null) {
        const target = ruleAttributeOptions.value.find(
          (item) => item.attributeCode === first.code
        )
        return target?.id
      }
      if (first && first.id != null) return first.id
      return undefined
    })()
    ruleForm.fieldRule = firstRule as any
    ruleForm.ruleAttributeId = firstAttrId as any
    ruleForm.ruleOperator = first.operator as any
    ruleForm.ruleValue = first.operatorRule as any
    extraPointRules.value = list.slice(1).map((item: any) => ({
      id: (() => {
        if (item && item.code != null) {
          const target = ruleAttributeOptions.value.find(
            (opt) => opt.attributeCode === item.code
          )
          return target?.id
        }
        if (item && item.id != null) return item.id
        return undefined
      })(),
      rule: item.rule,
      operator: item.operator,
      operatorRule: item.operatorRule,
    }))
    if (identifier === 'COUNT') {
      const parsedFieldRule = parseCountFieldRule(row.fieldRule)
      if (parsedFieldRule.length) {
        countArithmeticRules.value = parsedFieldRule
      } else {
        const parsedList = list.map((item: any) => ({
        ruleAttributeId: resolveRuleAttributeIdByCode(item?.code),
        ruleOperator: item?.operator,
        ruleValue: item?.operatorRule,
        }))
        const filteredParsedList = parsedList.filter((item) => {
          return item.ruleAttributeId && item.ruleOperator && String(item.ruleValue ?? '').trim() !== ''
        })
        countArithmeticRules.value = filteredParsedList.length
          ? filteredParsedList
          : [createEmptyCountArithmeticRule()]
      }
    }
  } else {
    ruleForm.fieldRule = row.fieldRule
    ruleForm.ruleAttributeId = row.ruleAttributeId
    ruleForm.ruleOperator = row.ruleOperator
    ruleForm.ruleValue = row.ruleValue as any
    if (identifier === 'COUNT') {
      const parsedFieldRule = parseCountFieldRule(row.fieldRule)
      countArithmeticRules.value = parsedFieldRule.length
        ? parsedFieldRule
        : [
          {
            ruleAttributeId: row.ruleAttributeId,
            ruleOperator: row.ruleOperator,
            ruleValue: row.ruleValue as any,
          },
        ]
    }
  }

  const options = currentRuleOptions.value
  if (options.length && !options.some((item) => item.value === ruleForm.fieldRule)) {
    ruleForm.fieldRule = options[0].value
  }
  ruleDialogVisible.value = true
}

const handleRuleSubmit = async () => {
  if (!ruleForm.id) return
  try {
    ruleFormLoading.value = true
    if (isCountIdentifier.value) {
      const hasIncompleteRule = countArithmeticRules.value.some((item) => {
        return !item.ruleAttributeId || !item.ruleOperator || String(item.ruleValue ?? '').trim() === ''
      })
      if (hasIncompleteRule) {
        message.warning('请完整填写每一组四则运算规则')
        return
      }
      const normalizedRules = countArithmeticRules.value.filter((item) => {
        return item.ruleAttributeId && item.ruleOperator && String(item.ruleValue ?? '').trim() !== ''
      })
      if (!normalizedRules.length) {
        message.warning('请至少填写一组四则运算规则')
        return
      }
      for (let i = 0; i < normalizedRules.length - 1; i++) {
        if (!normalizedRules[i].bigOperator) {
          message.warning(`请为第${i + 1}组选择连接运算符`)
          return
        }
      }
      for (let i = 0; i < normalizedRules.length; i++) {
        const item = normalizedRules[i]
        if (item.ruleOperator !== '/') continue
        const valueText = String(item.ruleValue ?? '').trim()
        if (valueText !== '' && !Number.isNaN(Number(valueText)) && Number(valueText) === 0) {
          message.warning(`第${i + 1}组为除法时，数值不能为0`)
          return
        }
      }
      const fieldRule = buildCountFieldRule(normalizedRules)
      if (!fieldRule) {
        message.warning('四则运算规则格式不正确')
        return
      }
      const payload = {
        id: ruleForm.id,
        identifier: ruleForm.identifier,
        fieldName: ruleForm.fieldName,
        fieldRule,
        defaultValue: ruleForm.defaultValue,
        deviceId: ruleForm.deviceId ?? attributeDeviceId.value,
      }
      await request.put({ url: '/iot/device-point-rules/update', data: payload })
      message.success(t('common.updateSuccess'))
      ruleDialogVisible.value = false
      await getRuleList()
      return
    }
    const alarmRunningFieldRule = buildAlarmRunningFieldRule()
    if (!alarmRunningFieldRule || alarmRunningFieldRule === '[]') {
      message.warning('请至少填写一组规则')
      return
    }
    const payload = {
      id: ruleForm.id,
      identifier: ruleForm.identifier,
      fieldName: ruleForm.fieldName,
      fieldRule: alarmRunningFieldRule,
      defaultValue: ruleForm.defaultValue,
      deviceId: ruleForm.deviceId ?? attributeDeviceId.value,
    } as any
    if (!isCountIdentifier.value) {
      payload.alarmLevel = ruleForm.alarmLevel
    }

    await request.put({ url: '/iot/device-point-rules/update', data: payload })
    message.success(t('common.updateSuccess'))
    ruleDialogVisible.value = false
    await getRuleList()
  } finally {
    ruleFormLoading.value = false
  }
}

const handleRuleDelete = async (id: number) => {
  if (!id) return
  try {
    await message.delConfirm()
    await request.delete({ url: '/iot/device-point-rules/delete?id=' + id })
    message.success(t('common.delSuccess'))
    await getRuleList()
  } catch { }
}

const handleAddPointRule = () => {
  if (!isRunningIdentifier.value) return
  const allOptions = currentRuleOptions.value || []
  const used = new Set<string>()
  if (ruleForm.fieldRule) used.add(String(ruleForm.fieldRule))
  extraPointRules.value.forEach((item) => {
    if (item.rule != null) used.add(String(item.rule))
  })
  const next = allOptions.find((opt) => !used.has(String(opt.value)))
  if (!next) {
    message.warning('已没有可用的点位规则可选')
    return
  }
  extraPointRules.value.push({
    rule: next.value as any,
    id: undefined,
    operator: undefined,
    operatorRule: undefined,
  })
}

const handleRemovePointRule = (index: number) => {
  if (index < 0 || index >= extraPointRules.value.length) return
  extraPointRules.value.splice(index, 1)
}

const createRuleDialogVisible = ref(false)
const createRuleFormLoading = ref(false)
const createRuleFormRef = ref()
const createRuleForm = reactive({
  identifier: 'ALARM',
  fieldName: '',
  defaultValue: '报警',
  alarmLevel: '',
})
const isCreateCountRule = computed(() => {
  return createRuleForm.identifier.toString().toUpperCase() === 'COUNT'
})
const createRuleDialogTitle = computed(() => {
  if (isCreateCountRule.value) return '新增产量'
  return t('DataCollection.DeviceModel.ruleCreateButton')
})

const openCreateRuleForm = () => {
  if (!attributeDeviceId.value) {
    message.error('请先选择设备')
    return
  }
  createRuleForm.identifier = 'ALARM'
  createRuleForm.fieldName = '报警'
  createRuleForm.defaultValue = '报警'
  createRuleForm.alarmLevel = ''
  createRuleDialogVisible.value = true
}
const openCreateCountRuleForm = () => {
  if (!attributeDeviceId.value) {
    message.error('请先选择设备')
    return
  }
  createRuleForm.identifier = 'COUNT'
  createRuleForm.fieldName = '产能'
  createRuleForm.defaultValue = '产能'
  createRuleForm.alarmLevel = ''
  createRuleDialogVisible.value = true
}

const handleCreateRuleSubmit = async () => {
  if (!attributeDeviceId.value) return
  if (!createRuleForm.fieldName) {
    message.warning('请输入名称')
    return
  }
  try {
    createRuleFormLoading.value = true
    const payload = {
      identifier: createRuleForm.identifier,
      fieldName: createRuleForm.fieldName,
      defaultValue: createRuleForm.defaultValue,
      deviceId: attributeDeviceId.value,
    } as any
    if (!isCreateCountRule.value) {
      payload.alarmLevel = createRuleForm.alarmLevel
    }
    await request.post({ url: '/iot/device-point-rules/create', data: payload })
    message.success('新增成功')
    createRuleDialogVisible.value = false
    await getRuleList()
  } finally {
    createRuleFormLoading.value = false
  }
}
const connectLoadingMap = reactive<Record<number, boolean>>({})

const getRowConnectValue = (row: any) => {
  return row?.isConnect ?? row?.status
}

const isRowConnected = (row: any) => {
  return String(getRowConnectValue(row)) === '1'
}

const handleEdit = async (row: DeviceVO) => {
  if (isRowConnected(row)) {
    await message.alertWarning('设备在线状态，无法编辑，请先断开连接')
    return
  }
  openForm('update', row.id)
}

const handleToggleConnect = async (row: DeviceVO) => {
  const id = row?.id
  if (!id) {
    message.error('设备信息不完整')
    return
  }

  const nextIsConnect = isRowConnected(row) ? '2' : '1'
  const actionText = nextIsConnect === '1' ? '连接' : '断开连接'

  try {
    await message.confirm(`确认${actionText}设备“${row.deviceName ?? ''}”吗？`)
    connectLoadingMap[id] = true

    const params: DeviceConnectParams = { id: String(id), isConnect: nextIsConnect }
    await DeviceApi.connectDevice(params)
    message.success(`${actionText}成功`)
    await getList()
  } catch {
  } finally {
    connectLoadingMap[id] = false
  }
}

let deviceTimer: number | undefined

const startDeviceTimer = () => {
  if (deviceTimer) return
  deviceTimer = window.setInterval(() => {
    getList(false)
  }, 5000)
}

const stopDeviceTimer = () => {
  if (!deviceTimer) return
  window.clearInterval(deviceTimer)
  deviceTimer = undefined
}

onMounted(() => {
  getList()
  startDeviceTimer()
})

onActivated(() => {
  startDeviceTimer()
})

onDeactivated(() => {
  stopDeviceTimer()
})

onBeforeUnmount(() => {
  stopDeviceTimer()
})

const deviceAlarmDialogVisible = ref(false)
const deviceAlarmLoading = ref(false)
const deviceAlarmList = ref<any[]>([])
const deviceAlarmTotal = ref(0)
const deviceAlarmQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  deviceId: undefined as number | undefined,
  modelId: undefined as number | undefined,
  rule: undefined as string | undefined,
  alarmLevel: undefined as string | undefined,
  addressValue: undefined as string | undefined,
  createTime: [] as string[],
  ruleId: undefined as number | undefined,
})
const deviceAlarmQueryFormRef = ref()
const deviceAlarmRuleOptions = ref<any[]>([])
const deviceAlarmPointOptions = ref<any[]>([])
const deviceAlarmRuleLoading = ref(false)
const deviceAlarmPointLoading = ref(false)

const loadDeviceAlarmRuleOptions = async () => {
  if (!attributeDeviceId.value) return
  deviceAlarmRuleLoading.value = true
  try {
    const res = await request.get({
      url: '/iot/device-point-rules/getList',
      params: { id: attributeDeviceId.value },
    })
    const data = (res as any)?.data ?? res
    const listData = Array.isArray((data as any)?.list)
      ? (data as any).list
      : Array.isArray(data)
      ? data
      : []
    deviceAlarmRuleOptions.value = listData as any[]
  } finally {
    deviceAlarmRuleLoading.value = false
  }
}

const loadDeviceAlarmPointOptions = async () => {
  if (!attributeDeviceId.value) return
  deviceAlarmPointLoading.value = true
  try {
    const res = await request.get({
      url: '/iot/device/device-attribute/list',
      params: { deviceId: attributeDeviceId.value },
    })
    const data = (res as any)?.data ?? res
    const listData = Array.isArray((data as any)?.list)
      ? (data as any).list
      : Array.isArray(data)
      ? data
      : []
    deviceAlarmPointOptions.value = listData as any[]
  } finally {
    deviceAlarmPointLoading.value = false
  }
}

const getDeviceAlarmList = async () => {
  if (!attributeDeviceId.value) return
  deviceAlarmLoading.value = true
  try {
    deviceAlarmQueryParams.deviceId = attributeDeviceId.value
    const params = {
      pageNo: deviceAlarmQueryParams.pageNo,
      pageSize: deviceAlarmQueryParams.pageSize,
      deviceId: deviceAlarmQueryParams.deviceId,
      modelId: deviceAlarmQueryParams.modelId,
      rule: deviceAlarmQueryParams.rule,
      alarmLevel: deviceAlarmQueryParams.alarmLevel,
      addressValue: deviceAlarmQueryParams.addressValue,
      createTime: deviceAlarmQueryParams.createTime,
      ruleId: deviceAlarmQueryParams.ruleId,
    }
    const data = await request.get({
      url: '/iot/device-warinning-record/page',
      params,
    })
    const listData = Array.isArray((data as any)?.list)
      ? (data as any).list
      : Array.isArray(data)
      ? data
      : []
    const totalData = (data as any)?.total ?? listData.length
    deviceAlarmList.value = listData as any[]
    deviceAlarmTotal.value = totalData
  } finally {
    deviceAlarmLoading.value = false
  }
}

const handleDeviceAlarmQuery = () => {
  if (!attributeDeviceId.value) return
  deviceAlarmQueryParams.pageNo = 1
  getDeviceAlarmList()
}

const resetDeviceAlarmQuery = () => {
  if (!attributeDeviceId.value) return
  deviceAlarmQueryFormRef.value?.resetFields?.()
  deviceAlarmQueryParams.pageNo = 1
  getDeviceAlarmList()
}

const handleShowDeviceAlarmHistory = async () => {
  if (!attributeDeviceId.value) {
    message.error(t('DataCollection.Device.messageSelectDeviceRequired'))
    return
  }
  deviceAlarmQueryParams.pageNo = 1
  deviceAlarmQueryParams.pageSize = 10
  deviceAlarmQueryParams.modelId = undefined
  deviceAlarmQueryParams.rule = undefined
  deviceAlarmQueryParams.alarmLevel = undefined
  deviceAlarmQueryParams.addressValue = undefined
  deviceAlarmQueryParams.createTime = []
  deviceAlarmQueryParams.ruleId = undefined
  deviceAlarmDialogVisible.value = true
  await Promise.all([loadDeviceAlarmRuleOptions(), loadDeviceAlarmPointOptions()])
  await getDeviceAlarmList()
}

</script>

<style lang="scss" scoped>
.simple-grid-view {
  background-color: #fff;
  border-radius: 4px;
  padding: 16px;
 /* max-height: calc(100vh - 546px);*/
  overflow-y: auto;

  .empty-grid {  // 注意：这里缩进要与上面一致
    display: flex;
    align-items: center;
    justify-content: center;
    height: 300px;
  }

  .grid-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 16px;
    padding: 8px;

    .grid-card {
      position: relative;
      border: 1px solid #ebeef5;
      border-radius: 8px;

      background-color: #fafafa;
      cursor: pointer;
      transition: all 0.3s ease;
      display: flex;
      align-items: center;
      gap: 16px;


      &:hover {
        border-color: #409eff;
        box-shadow: 0 4px 12px rgba(64, 158, 255, 0.1);
        transform: translateY(-2px);
        background-color: #fff;
      }

      .status-indicator {
        position: absolute;
        top: 0;
        left: 0;
        width: 6px;
        height: 100%;
        border-radius: 8px 0 0 8px;

        &.status-running {
          background-color: #67c23a;
        }

        &.status-standby {
          background-color: #909399;
        }

        &.status-fault {
          background-color: #f56c6c;
        }

        &.status-maintenance {
          background-color: #e6a23c;
        }

        &.status-stopped {
          background-color: #909399;
        }
      }

      .card-icon {
        flex-shrink: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 60px;
        height: 60px;
        background-color: #f5f7fa;
        border-radius: 8px;
      }

    }
  }

  .simple-pagination {
    margin-top: 24px;
    padding-top: 16px;
    border-top: 1px solid #ebeef5;
    text-align: center;
  }
}

// 响应式
@media (max-width: 768px) {
  .equipment-simple {
    padding: 12px;

    .simple-toolbar {
      flex-direction: column;
      gap: 12px;

      .toolbar-left {
        width: 100%;

        .simple-search {
          flex: 1;
          width: 100%;
        }

        .status-filter,
        .type-filter {
          width: 100px;
        }
      }

      .toolbar-right {
        width: 100%;
        justify-content: flex-end;
      }
    }

    .simple-grid-view {
      .grid-container {
        grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
      }
    }
  }
}

@media (max-width: 480px) {
  .equipment-simple {
    .simple-grid-view {
      .grid-container {
        grid-template-columns: 1fr;
      }
    }

    .simple-toolbar {
      .toolbar-left {
        flex-wrap: wrap;

        .simple-search {
          width: 100%;
        }

        .status-filter,
        .type-filter {
          flex: 1;
          min-width: 120px;
        }
      }
    }
  }
}
.device-card {
  width: 100%;

  background-color: white;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  overflow: hidden;
}

.header {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #eee;
}

.device-icon {
  width: 40px;
  height: 40px;
  background-color: #f0f7ff;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 12px;
}

.device-info {
  flex: 1;
}

.device-name {
  font-size: 16px;
  font-weight: 600;
  color: #333;
  margin-bottom: 4px;
}

.device-id {
  font-size: 12px;
  color: #999;
}


.content {
  padding: 10px;
}

.info-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid #f0f0f0;
}

.info-label {
  display: flex;
  align-items: center;
  color: #666;
  font-size: 14px;
}

.info-label i {
  margin-right: 6px;
  color: #1890ff;
}

.info-value {
  color: #333;
  font-size: 14px;
}

.toggle-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 0;
}

.toggle-label {
  color: #666;
  font-size: 14px;
}

.toggle-switch {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 24px;
}

.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  transition: .4s;
  border-radius: 24px;
}

.slider:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 3px;
  bottom: 3px;
  background-color: white;
  transition: .4s;
  border-radius: 50%;
}

input:checked + .slider {
  background-color: #1890ff;
}

input:checked + .slider:before {
  transform: translateX(20px);
}

.footer {
  display: flex;
  justify-content: space-between;
  padding: 16px 20px;
  border-top: 1px solid #eee;
}

.action-btn {
  display: flex;
  align-items: center;
  padding: 2px 4px;
  border-radius: 6px;
  font-size: 13px;
  //cursor: pointer;
  border: none;
  background-color: transparent;
}

.btn-primary {
  color: #1890ff;
  border: 1px solid #1890ff;
}

.btn-success {
  color: #28a745;
  border: 1px solid #28a745;
}

.action-btn i {
  margin-right: 6px;
  font-size: 16px;
}

.action-icons {
  display: flex;
}

.icon-btn {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f5f7fa;
  color: #666;
  cursor: pointer;
  border: none;
}

/* 基础样式 */
.status-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  display: inline-block;
}

/* 在线状态 */
.status-online {
  background-color: #e6f7e6;
  color: #67c23a;
  border: 1px solid rgba(40, 167, 69, 0.2);
}

.dot-online {
  background-color: #28a745;
  box-shadow: 0 0 4px rgba(40, 167, 69, 0.5);
}

/* 离线状态 */
.status-offline {
  background-color: #f5f5f5;
  color: #909399;
  border: 1px solid rgba(108, 117, 125, 0.2);
}

.dot-offline {
  background-color: #6c757d;
  box-shadow: 0 0 4px rgba(108, 117, 125, 0.3);
}

/* 运行中 */
.status-running {
  background-color: #67c23a;
  color: white;
  border: 1px solid rgba(24, 144, 255, 0.2);
}

.dot-running {
  background-color: #67c23a;
  animation: pulse 2s infinite;
  box-shadow: 0 0 4px rgba(24, 144, 255, 0.5);
}

@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.5; }
  100% { opacity: 1; }
}

/* 已停止 */
.status-stopped {
  background-color: #f5f5f5;
  color: #999;
  border: 1px solid rgba(153, 153, 153, 0.2);
}

.dot-stopped {
  background-color: #999;
}

/* 待机中 */
.status-standby {
  background-color: #f5f5f5;
  color: #999;
  border: 1px solid rgba(153, 153, 153, 0.2);
}

.dot-stopped {
  background-color: #999;
}

/* 故障 */
.status-fault {
  background-color: #fde8e8;
  color: #f5222d;
  border: 1px solid rgba(245, 34, 45, 0.2);
}

.dot-fault {
  background-color: #f5222d;
  box-shadow: 0 0 4px rgba(245, 34, 45, 0.5);
}

/* 报警 */
.status-alarm {
  background-color: #fff7e6;
  color: #fa8c16;
  border: 1px solid rgba(250, 140, 22, 0.2);
}

.dot-alarm {
  background-color: #fa8c16;
  animation: blink 1s infinite;
  box-shadow: 0 0 4px rgba(250, 140, 22, 0.5);
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

/* 维护中 */
.status-maintenance {
  background-color: #f0f7ff;
  color: #1890ff;
  border: 1px solid rgba(24, 144, 255, 0.2);
}

.dot-maintenance {
  background-color: #1890ff;
  animation: maintenance 3s infinite;
}

@keyframes maintenance {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.2); }
}

/* 未启用 */
.status-disabled {
  background-color: #fafafa;
  color: #bfbfbf;
  border: 1px solid rgba(191, 191, 191, 0.2);
  text-decoration: line-through;
}

.dot-disabled {
  background-color: #bfbfbf;
}

/* 默认状态 */
.status-default {
  background-color: #f5f5f5;
  color: #666;
  border: 1px solid rgba(102, 102, 102, 0.2);
}

.dot-default {
  background-color: #666;
}

</style>
