Просмотр исходного кода

feat(inspect): 重构巡检工单填写页布局样式

- 增加统一的页面标题区和返回按钮
- 重构巡检设备导航,展示设备巡检完成进度
- 移除设备与巡检项两级竖向导航结构
- 将巡检项进度调整为顶部横向展示
- 优化当前巡检项、填写表单和进度信息层级
- 将填写内容与巡检标准调整为左右双栏布局
- 优化长巡检标准和附件预览区域的滚动展示
- 重新排布巡检结果、异常描述及图片上传控件
- 统一表单标签宽度、行高和输入区域对齐方式
- 统一操作按钮尺寸并优化步骤切换操作区
- 增加中小屏上下布局和设备列表横向滚动适配
- 保留原有逐项校验、提交及附件预览逻辑
Zimo 1 неделя назад
Родитель
Сommit
0857fb6425
1 измененных файлов с 938 добавлено и 153 удалено
  1. 938 153
      src/views/pms/inspect/order/WriteOrder.vue

+ 938 - 153
src/views/pms/inspect/order/WriteOrder.vue

@@ -1,134 +1,183 @@
 <template>
-  <ContentWrap>
-    <el-tabs
-      v-model="activeTab"
-      type="border-card"
-      tab-position="left"
-      v-loading="loading"
-      style="height: 84vh"
-    >
-      <el-tab-pane
-        style="height: 100%"
-        v-for="(tab, tabIndex) in tabs"
-        :key="tab.deviceName"
-        :name="String(tabIndex)"
-      >
-        <template #label>
-          <span class="custom-label">
-            {{ tab.deviceName }} ({{ completedSteps(tabIndex) }}/{{ tab.orderDetails.length }})
-                  <el-tooltip :content="tab.routeDesc" placement="top" effect="dark">
-                    <Icon icon="ep:info-filled" />
-                  </el-tooltip>
-          </span>
-        </template>
-
-        <div class="step-container">
-          <el-steps direction="vertical" :active="currentStep[tabIndex]" class="steps-nav">
-            <el-step
+  <div class="write-order-page" v-loading="loading">
+    <header class="page-header">
+      <div class="page-header__main">
+        <div class="page-header__icon"><Icon icon="ep:edit-pen" /></div>
+        <div>
+          <h1>填写巡检工单</h1>
+          <p>按设备和巡检项顺序填写检查结果与异常信息</p>
+        </div>
+      </div>
+      <el-button size="default" @click="close">
+        <Icon icon="ep:arrow-left" class="mr-5px" />返回
+      </el-button>
+    </header>
+
+    <el-empty v-if="!loading && tabs.length === 0" class="empty-panel" description="暂无巡检设备" />
+    <div v-else class="inspection-workbench">
+      <aside class="device-panel">
+        <header class="device-panel__header">
+          <div>
+            <strong>巡检设备</strong>
+            <span>共 {{ tabs.length }} 台</span>
+          </div>
+        </header>
+        <div class="device-list">
+          <button
+            v-for="(tab, tabIndex) in tabs"
+            :key="`${tab.deviceId}-${tabIndex}`"
+            type="button"
+            class="device-item"
+            :class="{ 'is-active': activeTab === String(tabIndex) }"
+            @click="activeTab = String(tabIndex)">
+            <span class="device-item__icon"><Icon icon="ep:monitor" /></span>
+            <span class="device-item__content">
+              <span class="device-item__name">{{ tab.deviceName }}</span>
+              <span class="device-item__progress">
+                已完成 {{ completedSteps(tabIndex) }} / {{ tab.orderDetails.length }} 项
+              </span>
+            </span>
+            <Icon icon="ep:arrow-right" class="device-item__arrow" />
+          </button>
+        </div>
+      </aside>
+
+      <div class="device-content">
+        <section
+          v-for="(tab, tabIndex) in tabs"
+          v-show="activeTab === String(tabIndex)"
+          :key="`${tab.deviceId}-content`"
+          class="device-inspection-panel">
+          <header class="device-summary">
+            <div class="device-summary__main">
+              <div class="device-summary__icon"><Icon icon="ep:monitor" /></div>
+              <div>
+                <h2>{{ tab.deviceName }}</h2>
+                <p>{{ tab.routeDesc || '按巡检项顺序完成当前设备检查' }}</p>
+              </div>
+            </div>
+            <span class="device-summary__progress">
+              {{ completedSteps(tabIndex) }}/{{ tab.orderDetails.length }} 已完成
+            </span>
+          </header>
+
+          <div class="item-progress-strip">
+            <div
               v-for="(step, stepIndex) in tab.orderDetails"
               :key="stepIndex"
-              :title="`${step.item}`"
-              :status="getStepStatus(tabIndex, stepIndex)"
-            >
-              <template #title>
-                <div class="step-title-wrapper">
-                  <span class="title-text">{{ step.item }}</span>
-                  <el-tooltip :content="step.standard" placement="top" effect="dark">
-                    <Icon icon="ep:info-filled" />
-                  </el-tooltip>
+              class="progress-item"
+              :class="`is-${getStepStatus(tabIndex, stepIndex)}`">
+              <span class="progress-item__index">
+                <Icon v-if="getStepStatus(tabIndex, stepIndex) === 'finish'" icon="ep:check" />
+                <template v-else>{{ stepIndex + 1 }}</template>
+              </span>
+              <span class="progress-item__name">{{ step.item }}</span>
+            </div>
+          </div>
+
+          <div class="current-item-layout">
+            <section class="entry-section">
+              <header class="section-heading section-heading--between">
+                <div class="section-heading__title">
+                  <span></span>
+                  {{ tab.orderDetails[currentStep[tabIndex]].item }}
+                </div>
+                <div class="step-counter">
+                  第 {{ currentStep[tabIndex] + 1 }} / {{ tab.orderDetails.length }} 项
                 </div>
-              </template>
-            </el-step>
-          </el-steps>
+              </header>
 
-          <div class="form-wrapper">
-            <ContentWrap>
               <el-form
                 :model="formData[tabIndex][currentStep[tabIndex]]"
                 :rules="formRules"
                 ref="formRefs"
-                label-width="120px"
-              >
+                size="default"
+                label-width="96px"
+                class="inspection-form">
                 <el-form-item label="设备id" v-if="false" prop="deviceId">
                   <el-input
                     v-model="formData[tabIndex][currentStep[tabIndex]].deviceId"
                     :model-value="tab.deviceId"
-                    clearable
-                  />
-                </el-form-item>
-                <el-form-item :label="t('inspect.isException')" prop="ifNormal">
-                  <el-select
-                    v-model="formData[tabIndex][currentStep[tabIndex]].ifNormal"
-                    :placeholder="t('inspect.isException')"
-                    clearable
-                  >
-                    <el-option
-                      v-for="dict in getBoolDictOptions(DICT_TYPE.PMS_INSPECT_WRITE)"
-                      :key="dict.value"
-                      :label="dict.label"
-                      :value="dict.value"
-                    />
-                  </el-select>
-                </el-form-item>
-
-                <el-form-item
-                  :label="t('inspect.exceptionDes')"
-                  prop="description"
-                  :rules="formData[tabIndex][currentStep[tabIndex]].ifNormal ?  []: descriptionRule"
-                >
-                  <el-input
-                    v-model="formData[tabIndex][currentStep[tabIndex]].description"
-                    type="textarea"
-                    :rows="5"
-                    :placeholder="t('inspect.exceptionDes')"
-                  />
-                </el-form-item>
-
-                <el-form-item :label="t('deviceForm.picture')" prop="picUrl">
-                  <UploadImg
-                    v-model="formData[tabIndex][currentStep[tabIndex]].picUrl"
-                    height="55px"
-                    width="30em"
-                  />
+                    clearable />
                 </el-form-item>
+                <div class="form-grid">
+                  <el-form-item :label="t('inspect.isException')" prop="ifNormal">
+                    <el-select
+                      v-model="formData[tabIndex][currentStep[tabIndex]].ifNormal"
+                      :placeholder="t('inspect.isException')"
+                      clearable>
+                      <el-option
+                        v-for="dict in getBoolDictOptions(DICT_TYPE.PMS_INSPECT_WRITE)"
+                        :key="dict.value"
+                        :label="dict.label"
+                        :value="dict.value" />
+                    </el-select>
+                  </el-form-item>
+                  <el-form-item :label="t('deviceForm.picture')" prop="picUrl">
+                    <UploadImg
+                      v-model="formData[tabIndex][currentStep[tabIndex]].picUrl"
+                      height="55px"
+                      width="120px" />
+                  </el-form-item>
+                  <el-form-item
+                    :label="t('inspect.exceptionDes')"
+                    prop="description"
+                    class="form-grid__wide"
+                    :rules="
+                      formData[tabIndex][currentStep[tabIndex]].ifNormal ? [] : descriptionRule
+                    ">
+                    <el-input
+                      v-model="formData[tabIndex][currentStep[tabIndex]].description"
+                      type="textarea"
+                      :rows="5"
+                      :placeholder="t('inspect.exceptionDes')" />
+                  </el-form-item>
+                </div>
               </el-form>
+            </section>
 
-              <div class="navigation-controls">
-                <el-button :disabled="currentStep[tabIndex] === 0" @click="handlePrev(tabIndex)">
-                  上一步
-                </el-button>
-
-                <el-button
-                  type="primary"
-                  :disabled="!isStepValid(tabIndex)"
-                  @click="handleNext(tabIndex, tab.deviceId)"
-                >
-                  {{ isLastStep(tabIndex) ? '完成提交' : '下一步' }}
-                </el-button>
+            <aside class="standard-section">
+              <header class="standard-section__header">
+                <Icon icon="ep:notebook-2" />
+                <span>{{ t('inspect.InspectionStandards') }}</span>
+              </header>
+              <div class="standard-section__content">
+                {{ tab.orderDetails[currentStep[tabIndex]].standard || '-' }}
               </div>
-            </ContentWrap>
-            <ContentWrap style="margin-top: 50px">
-              <el-card>
-                <span style="font-weight: bold">{{ t('inspect.InspectionStandards') }}:</span
-                >{{ tab.orderDetails[currentStep[tabIndex]].standard }}<br />
-                <el-divider />
-                <span style="font-weight: bold">{{ t('fileInfo.appendix') }}:</span>
+              <footer class="standard-section__footer">
+                <span>{{ t('fileInfo.appendix') }}</span>
                 <el-button
                   v-if="tab.orderDetails[currentStep[tabIndex]].urls"
                   link
                   type="primary"
-                  @click="openWeb(tab.orderDetails[currentStep[tabIndex]].urls)"
-                >
-                  <Icon size="19" icon="ep:view" />
-                  {{ t('action.preview') }}
+                  @click="openWeb(tab.orderDetails[currentStep[tabIndex]].urls)">
+                  <Icon icon="ep:view" class="mr-5px" />{{ t('action.preview') }}
                 </el-button>
-              </el-card>
-            </ContentWrap>
+                <span v-else>-</span>
+              </footer>
+            </aside>
           </div>
-        </div>
-      </el-tab-pane>
-    </el-tabs>
-  </ContentWrap>
+
+          <div class="navigation-controls">
+            <el-button
+              size="default"
+              :disabled="currentStep[tabIndex] === 0"
+              @click="handlePrev(tabIndex)">
+              <Icon icon="ep:arrow-left" class="mr-5px" />上一步
+            </el-button>
+            <el-button
+              size="default"
+              type="primary"
+              :disabled="!isStepValid(tabIndex)"
+              @click="handleNext(tabIndex, tab.deviceId)">
+              {{ isLastStep(tabIndex) ? '完成提交' : '下一步' }}
+              <Icon :icon="isLastStep(tabIndex) ? 'ep:check' : 'ep:arrow-right'" class="ml-5px" />
+            </el-button>
+          </div>
+        </section>
+      </div>
+    </div>
+  </div>
 </template>
 
 <script setup>
@@ -160,6 +209,11 @@ const openWeb = (url) => {
     'http://1.94.244.160:8012/onlinePreview?url=' + encodeURIComponent(Base64.encode(url))
   )
 }
+
+const close = () => {
+  delView(unref(currentRoute))
+  push({ name: 'IotInspectOrder', params: {} })
+}
 // 响应式状态
 const loading = ref(true)
 const activeTab = ref('0')
@@ -265,78 +319,809 @@ const submitForm = (tabIndex, current, type) => {
 </script>
 
 <style scoped>
-.step-container {
+@media (width <= 1400px) {
+  .write-order-page .device-tabs :deep(.el-tabs__header.is-left) {
+    width: 210px;
+  }
+
+  .write-order-page .inspection-workspace {
+    grid-template-columns: 220px minmax(0, 1fr);
+  }
+}
+
+@media (width <= 1100px) {
+  .write-order-page .inspection-workspace {
+    grid-template-columns: minmax(0, 1fr);
+    grid-template-rows: 220px minmax(0, 1fr);
+  }
+
+  .write-order-page .steps-panel {
+    border-right: 0;
+    border-bottom: 1px solid var(--el-border-color-lighter);
+  }
+}
+
+@media (width <= 768px) {
+  .write-order-page .page-header {
+    align-items: flex-start;
+  }
+
+  .write-order-page .page-header p {
+    display: none;
+  }
+
+  .write-order-page .device-tabs :deep(.el-tabs__header.is-left) {
+    width: 170px;
+  }
+
+  .write-order-page .custom-label__progress {
+    display: none;
+  }
+
+  .write-order-page .step-panel__content {
+    padding: 16px 12px 0;
+  }
+
+  .write-order-page .inspection-form {
+    max-width: none;
+  }
+
+  .write-order-page .standard-panel {
+    padding: 12px;
+  }
+}
+
+.write-order-page {
+  display: flex;
+  min-height: calc(
+    100vh - 20px - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height)
+  );
+  flex-direction: column;
+  gap: 12px;
+}
+
+.page-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  min-height: 66px;
+  padding: 12px 16px;
+  background: var(--el-bg-color);
+  border-radius: 8px;
+  box-shadow: var(--el-box-shadow-light);
+}
+
+.page-header__main {
+  display: flex;
+  align-items: center;
+  min-width: 0;
+}
+
+.page-header__icon {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 38px;
+  height: 38px;
+  margin-right: 12px;
+  font-size: 18px;
+  color: var(--el-color-primary);
+  background: var(--el-color-primary-light-9);
+  border: 1px solid var(--el-color-primary-light-7);
+  border-radius: 8px;
+}
+
+.page-header h1 {
+  margin: 0;
+  font-size: 17px;
+  font-weight: 600;
+  line-height: 24px;
+  color: var(--el-text-color-primary);
+}
+
+.page-header p {
+  margin: 1px 0 0;
+  font-size: 12px;
+  line-height: 18px;
+  color: var(--el-text-color-secondary);
+}
+
+.empty-panel {
+  min-height: 480px;
+  background: var(--el-bg-color);
+  border-radius: 8px;
+  box-shadow: var(--el-box-shadow-light);
+  flex: 1;
+}
+
+.device-tabs {
+  display: flex;
+  min-height: 580px;
+  overflow: hidden;
+  background: var(--el-bg-color);
+  border-radius: 8px;
+  box-shadow: var(--el-box-shadow-light);
+  flex: 1;
+}
+
+.device-tabs :deep(.el-tabs__header.is-left) {
+  width: 240px;
+  margin-right: 0;
+  overflow: hidden;
+  background: var(--el-fill-color-extra-light);
+  flex: 0 0 auto;
+}
+
+.device-tabs :deep(.el-tabs__nav-wrap.is-left) {
+  height: 100%;
+}
+
+.device-tabs :deep(.el-tabs__item.is-left) {
+  justify-content: flex-start;
+  height: 48px;
+  padding: 0 14px;
+}
+
+.device-tabs :deep(.el-tabs__content) {
+  height: 100%;
+  min-width: 0;
+  padding: 0;
+  overflow: hidden;
+  flex: 1;
+}
+
+.device-tabs :deep(.el-tab-pane) {
+  height: 100%;
+}
+
+.custom-label {
+  display: flex;
+  align-items: center;
+  width: 100%;
+  min-width: 0;
+  gap: 8px;
+}
+
+.custom-label__name {
+  min-width: 0;
+  overflow: hidden;
+  font-weight: 500;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  flex: 1;
+}
+
+.custom-label__progress {
+  font-size: 12px;
+  color: var(--el-text-color-secondary);
+  flex: 0 0 auto;
+}
+
+.custom-label__info,
+.step-info {
+  color: var(--el-color-primary);
+  flex: 0 0 auto;
+}
+
+.inspection-workspace {
   display: grid;
-  grid-template-columns: 220px 1fr;
-  gap: 10px;
+  grid-template-columns: 260px minmax(0, 1fr);
   height: 100%;
-  min-height: 600px;
+  min-height: 0;
 }
 
-.steps-nav {
+.steps-panel {
+  display: flex;
+  min-width: 0;
+  overflow: hidden;
+  background: var(--el-fill-color-blank);
+  border-right: 1px solid var(--el-border-color-lighter);
+  flex-direction: column;
+}
+
+.steps-panel__header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 44px;
+  padding: 0 16px;
+  font-size: 14px;
+  font-weight: 600;
+  color: var(--el-text-color-primary);
+  background: var(--el-fill-color-extra-light);
+  border-bottom: 1px solid var(--el-border-color-lighter);
+}
+
+.steps-panel__header span:last-child {
+  font-size: 12px;
+  font-weight: 400;
+  color: var(--el-text-color-secondary);
+}
+
+.steps-panel__body {
+  min-height: 0;
+  padding: 18px 12px 10px 18px;
   overflow-y: auto;
-  padding-right: 15px;
+  flex: 1;
 }
 
-.form-wrapper {
-  background: #fff;
-  padding: 30px;
-  border-radius: 8px;
-  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+.steps-nav {
+  min-height: 100%;
 }
 
-.navigation-controls {
-  margin-top: 40px;
-  text-align: center;
+.steps-nav :deep(.el-step__title) {
+  min-width: 0;
+  font-size: 14px;
+  line-height: 22px;
 }
 
-.custom-label {
-  font-weight: 1000;
-  font-size: 17px;
-  padding: 0 10px;
+.steps-nav :deep(.el-step__head.is-process .el-step__icon) {
+  color: #fff;
+  background: var(--el-color-primary);
+  border-color: var(--el-color-primary);
 }
-::v-deep .el-step__icon {
-  background-color: #409eff;
+
+.steps-nav :deep(.el-step__head.is-finish .el-step__icon) {
   color: #fff;
-  border: 0px;
+  background: var(--el-color-success);
+  border-color: var(--el-color-success);
 }
+
 .step-title-wrapper {
-  display: inline-flex;
+  display: flex;
+  align-items: flex-start;
+  min-width: 0;
+  padding-right: 8px;
+  gap: 6px;
+}
+
+.title-text {
+  min-width: 0;
+  overflow-wrap: anywhere;
+}
+
+.step-panel {
+  display: flex;
+  min-width: 0;
+  min-height: 0;
+  flex-direction: column;
+}
+
+.section-heading {
+  display: flex;
+  align-items: center;
+  height: 44px;
+  padding: 0 16px;
+  font-size: 15px;
+  font-weight: 600;
+  color: var(--el-text-color-primary);
+  background: var(--el-fill-color-extra-light);
+  border-bottom: 1px solid var(--el-border-color-lighter);
+}
+
+.section-heading--between {
+  justify-content: space-between;
+}
+
+.section-heading__title {
+  display: flex;
   align-items: center;
+  min-width: 0;
+}
+
+.section-heading__title > span {
+  width: 4px;
+  height: 17px;
+  margin-right: 9px;
+  background: var(--el-color-primary);
+  border-radius: 2px;
+  flex: 0 0 auto;
+}
+
+.step-counter {
+  margin-left: 16px;
+  font-size: 13px;
+  font-weight: 400;
+  color: var(--el-text-color-secondary);
+  white-space: nowrap;
+}
+
+.step-panel__content {
+  display: flex;
+  min-height: 0;
+  padding: 24px 24px 0;
+  overflow-y: auto;
+  flex: 1;
+  flex-direction: column;
+}
+
+.inspection-form {
+  width: 100%;
+  max-width: 920px;
+}
+
+.inspection-form :deep(.el-form-item) {
+  margin-bottom: 20px;
+}
+
+.inspection-form :deep(.el-select),
+.inspection-form :deep(.el-input) {
+  width: 100%;
+}
+
+.standard-panel {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  padding: 14px 16px;
+  margin-top: 4px;
+  background: var(--el-fill-color-extra-light);
+  border: 1px solid var(--el-border-color-lighter);
+  border-radius: 6px;
+  gap: 10px;
+}
+
+.standard-item {
+  display: flex;
+  min-width: 0;
+  align-items: flex-start;
+}
+
+.standard-item__label {
+  width: 110px;
+  margin-right: 10px;
+  font-weight: 600;
+  color: var(--el-text-color-regular);
+  flex: 0 0 auto;
+}
+
+.standard-item__value {
+  min-width: 0;
+  color: var(--el-text-color-secondary);
+  overflow-wrap: anywhere;
+}
+
+.navigation-controls {
+  position: sticky;
+  bottom: 0;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  min-height: 60px;
+  padding: 10px 0;
+  margin-top: auto;
+  background: var(--el-bg-color);
+  border-top: 1px solid var(--el-border-color-lighter);
   gap: 8px;
-  position: relative;
-  padding-right: 25px;
 }
 
-/* 覆盖步骤条默认样式 */
-:deep(.custom-steps) {
-  /* 调整头部位置 */
-  .el-step__head {
-    top: 3px;
+.navigation-controls :deep(.el-button) {
+  margin-left: 0;
+}
+
+@media (width <= 1400px) {
+  .write-order-page .inspection-workbench {
+    grid-template-columns: 250px minmax(0, 1fr);
+  }
+
+  .write-order-page .current-item-layout {
+    grid-template-columns: minmax(0, 1fr) 380px;
   }
+}
+
+@media (width <= 1200px) {
+  .write-order-page .current-item-layout {
+    grid-template-columns: minmax(0, 1fr);
+  }
+
+  .write-order-page .standard-section__content {
+    max-height: 220px;
+  }
+}
 
-  /* 标题容器定位 */
-  .el-step__title {
-    display: inline-block;
-    margin-left: 10px;
-    padding-right: 0;
+@media (width <= 900px) {
+  .write-order-page .inspection-workbench {
+    grid-template-columns: minmax(0, 1fr);
+    grid-template-rows: auto minmax(520px, 1fr);
   }
 
-  /* 步骤连接线 */
-  .el-step__line {
-    left: 11px;
-    background-color: #ebeef5;
+  .write-order-page .device-panel {
+    border-right: 0;
+    border-bottom: 1px solid var(--el-border-color-lighter);
   }
 
-  /* 当前步骤样式 */
-  .is-process .title-text {
-    font-weight: 600;
-    color: #409eff;
+  .write-order-page .device-list {
+    flex-direction: row;
+    padding: 10px;
+    overflow-x: auto;
   }
 
-  /* 完成状态图标 */
-  .is-finish .tip-icon {
-    color: #67c23a;
+  .write-order-page .device-item {
+    width: 240px;
+    flex: 0 0 auto;
   }
 }
+
+@media (width <= 600px) {
+  .write-order-page .device-summary,
+  .write-order-page .section-heading--between {
+    align-items: flex-start;
+  }
+
+  .write-order-page .device-summary__progress,
+  .write-order-page .step-counter {
+    margin-top: 3px;
+  }
+
+  .write-order-page .current-item-layout {
+    padding: 12px;
+  }
+
+  .write-order-page .form-grid {
+    grid-template-columns: minmax(0, 1fr);
+  }
+
+  .write-order-page .form-grid__wide {
+    grid-column: auto;
+  }
+}
+
+.inspection-workbench {
+  display: grid;
+  grid-template-columns: 280px minmax(0, 1fr);
+  min-height: 580px;
+  overflow: hidden;
+  background: var(--el-bg-color);
+  border: 1px solid var(--el-border-color-lighter);
+  border-radius: 8px;
+  box-shadow: var(--el-box-shadow-light);
+  flex: 1;
+}
+
+.device-panel {
+  display: flex;
+  min-width: 0;
+  overflow: hidden;
+  background: var(--el-fill-color-extra-light);
+  border-right: 1px solid var(--el-border-color-lighter);
+  flex-direction: column;
+}
+
+.device-panel__header {
+  display: flex;
+  align-items: center;
+  min-height: 54px;
+  padding: 10px 16px;
+  background: var(--el-bg-color);
+  border-bottom: 1px solid var(--el-border-color-lighter);
+}
+
+.device-panel__header > div {
+  display: flex;
+  align-items: baseline;
+  justify-content: space-between;
+  width: 100%;
+  gap: 12px;
+}
+
+.device-panel__header strong {
+  font-size: 15px;
+  color: var(--el-text-color-primary);
+}
+
+.device-panel__header span {
+  font-size: 12px;
+  color: var(--el-text-color-secondary);
+}
+
+.device-list {
+  display: flex;
+  min-height: 0;
+  padding: 10px;
+  overflow-y: auto;
+  flex: 1;
+  flex-direction: column;
+  gap: 6px;
+}
+
+.device-item {
+  display: flex;
+  align-items: center;
+  width: 100%;
+  min-height: 58px;
+  padding: 9px 10px;
+  color: var(--el-text-color-regular);
+  text-align: left;
+  cursor: pointer;
+  background: transparent;
+  border: 1px solid transparent;
+  border-radius: 6px;
+  transition:
+    color 0.2s ease,
+    background-color 0.2s ease,
+    border-color 0.2s ease;
+  gap: 10px;
+}
+
+.device-item:hover {
+  background: var(--el-fill-color-light);
+}
+
+.device-item.is-active {
+  color: var(--el-color-primary);
+  background: var(--el-color-primary-light-9);
+  border-color: var(--el-color-primary-light-7);
+}
+
+.device-item__icon {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 30px;
+  height: 30px;
+  font-size: 15px;
+  color: var(--el-text-color-secondary);
+  background: var(--el-bg-color);
+  border: 1px solid var(--el-border-color-lighter);
+  border-radius: 6px;
+  flex: 0 0 auto;
+}
+
+.device-item.is-active .device-item__icon {
+  color: var(--el-color-primary);
+  border-color: var(--el-color-primary-light-7);
+}
+
+.device-item__content {
+  display: flex;
+  min-width: 0;
+  flex: 1;
+  flex-direction: column;
+  gap: 2px;
+}
+
+.device-item__name {
+  overflow: hidden;
+  font-size: 14px;
+  font-weight: 500;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.device-item__progress {
+  font-size: 12px;
+  color: var(--el-text-color-secondary);
+}
+
+.device-item__arrow {
+  color: var(--el-text-color-placeholder);
+  flex: 0 0 auto;
+}
+
+.device-content {
+  min-width: 0;
+  min-height: 0;
+  overflow: auto;
+}
+
+.device-inspection-panel {
+  display: flex;
+  min-height: 100%;
+  flex-direction: column;
+}
+
+.device-summary {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  min-height: 70px;
+  padding: 12px 18px;
+  border-bottom: 1px solid var(--el-border-color-lighter);
+  gap: 16px;
+}
+
+.device-summary__main {
+  display: flex;
+  align-items: center;
+  min-width: 0;
+}
+
+.device-summary__icon {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 36px;
+  height: 36px;
+  margin-right: 12px;
+  font-size: 17px;
+  color: var(--el-color-primary);
+  background: var(--el-color-primary-light-9);
+  border-radius: 7px;
+  flex: 0 0 auto;
+}
+
+.device-summary h2 {
+  margin: 0;
+  font-size: 16px;
+  font-weight: 600;
+  line-height: 24px;
+  color: var(--el-text-color-primary);
+}
+
+.device-summary p {
+  margin: 1px 0 0;
+  overflow: hidden;
+  font-size: 12px;
+  line-height: 18px;
+  color: var(--el-text-color-secondary);
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.device-summary__progress {
+  font-size: 13px;
+  color: var(--el-text-color-secondary);
+  white-space: nowrap;
+}
+
+.item-progress-strip {
+  display: flex;
+  padding: 12px 18px;
+  overflow-x: auto;
+  background: var(--el-fill-color-extra-light);
+  border-bottom: 1px solid var(--el-border-color-lighter);
+  gap: 8px;
+}
+
+.progress-item {
+  display: flex;
+  max-width: 240px;
+  min-width: 150px;
+  padding: 7px 10px;
+  color: var(--el-text-color-secondary);
+  background: var(--el-bg-color);
+  border: 1px solid var(--el-border-color-lighter);
+  border-radius: 6px;
+  align-items: center;
+  gap: 8px;
+}
+
+.progress-item.is-process {
+  color: var(--el-color-primary);
+  border-color: var(--el-color-primary-light-5);
+}
+
+.progress-item.is-finish {
+  color: var(--el-color-success);
+  border-color: var(--el-color-success-light-5);
+}
+
+.progress-item__index {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 22px;
+  height: 22px;
+  font-size: 12px;
+  color: #fff;
+  background: var(--el-text-color-placeholder);
+  border-radius: 50%;
+  flex: 0 0 auto;
+}
+
+.progress-item.is-process .progress-item__index {
+  background: var(--el-color-primary);
+}
+
+.progress-item.is-finish .progress-item__index {
+  background: var(--el-color-success);
+}
+
+.progress-item__name {
+  min-width: 0;
+  overflow: hidden;
+  font-size: 13px;
+  font-weight: 500;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.current-item-layout {
+  display: grid;
+  grid-template-columns: minmax(0, 1.2fr) minmax(360px, 0.8fr);
+  padding: 18px;
+  align-items: start;
+  gap: 16px;
+}
+
+.entry-section,
+.standard-section {
+  overflow: hidden;
+  border: 1px solid var(--el-border-color-lighter);
+  border-radius: 7px;
+}
+
+.entry-section .inspection-form {
+  max-width: none;
+  padding: 18px 18px 0;
+}
+
+.form-grid {
+  display: grid;
+  grid-template-columns: repeat(2, minmax(0, 1fr));
+  column-gap: 20px;
+}
+
+.form-grid :deep(.el-form-item) {
+  min-width: 0;
+  align-items: flex-start;
+}
+
+.form-grid :deep(.el-form-item__label) {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  height: 32px;
+  padding-right: 12px;
+  line-height: 32px;
+  white-space: nowrap;
+}
+
+.form-grid :deep(.el-form-item__content) {
+  min-width: 0;
+}
+
+.form-grid__wide {
+  grid-column: 1 / -1;
+}
+
+.standard-section {
+  background: var(--el-fill-color-extra-light);
+}
+
+.standard-section__header {
+  display: flex;
+  align-items: center;
+  height: 44px;
+  padding: 0 14px;
+  font-size: 14px;
+  font-weight: 600;
+  color: var(--el-text-color-primary);
+  background: var(--el-bg-color);
+  border-bottom: 1px solid var(--el-border-color-lighter);
+  gap: 8px;
+}
+
+.standard-section__header > :first-child {
+  color: var(--el-color-primary);
+}
+
+.standard-section__content {
+  max-height: 300px;
+  padding: 14px;
+  overflow-y: auto;
+  font-size: 14px;
+  line-height: 1.8;
+  color: var(--el-text-color-regular);
+  white-space: pre-wrap;
+}
+
+.standard-section__footer {
+  display: flex;
+  align-items: center;
+  min-height: 42px;
+  padding: 6px 14px;
+  font-size: 13px;
+  color: var(--el-text-color-secondary);
+  background: var(--el-bg-color);
+  border-top: 1px solid var(--el-border-color-lighter);
+  gap: 12px;
+}
+
+.device-inspection-panel > .navigation-controls {
+  position: static;
+  min-height: 58px;
+  padding: 10px 18px;
+  margin-top: 0;
+  border-top: 1px solid var(--el-border-color-lighter);
+}
 </style>