瀏覽代碼

设备台账

lipenghui 3 月之前
父節點
當前提交
e7b9594b3d

+ 8 - 7
src/views/pms/device/IotDeviceForm.vue

@@ -269,8 +269,6 @@
                 v-model="formData[field.code]"
                 :placeholder="'请输入' + field.name"
                 :type="field.type || 'text'"
-                clearable
-                :model-value="field.value"
               />
 
               <el-select
@@ -526,11 +524,14 @@ const submitForm = async () => {
   formLoading.value = true
   try {
     if (list.value) {
-      list.value.forEach((item) => {
-        item.value = formData.value[item.identifier]
-      })
+      list.value = list.value.map(item => ({
+        ...item,
+        value: formData.value[item.code] // 自定义属性生成逻辑
+      }))
+      debugger
+      formData.value.templateJson = JSON.stringify(list.value)
     }
-    formData.value.templateJson = JSON.stringify(list.value)
+    debugger
     const data = formData.value as unknown as IotDeviceVO
     if (formType.value === 'create') {
       await IotDeviceApi.createIotDevice(data)
@@ -571,7 +572,7 @@ onMounted(async () => {
       supplierLabel.value = iotDevice.supplierName;
       list.value = JSON.parse(iotDevice.templateJson);
       list.value.forEach((item) => {
-        formData.value[item.identifier] = item.value;
+        formData.value[item.code] = item.value;
       })
     } finally {
       formLoading.value = false

+ 7 - 0
src/views/pms/inspect/order/WriteOrder.vue

@@ -58,6 +58,13 @@
               ref="formRefs"
               label-width="120px"
             >
+              <el-form-item label="设备id" prop="deviceId">
+                <el-input
+                  v-model="formData[tabIndex][currentStep[tabIndex]].deviceId"
+                  :model-value="tab.deviceId"
+                  clearable
+                />
+              </el-form-item>
               <el-form-item label="是否异常" prop="ifNormal">
                 <el-select
                   v-model="formData[tabIndex][currentStep[tabIndex]].ifNormal"

+ 354 - 0
src/views/pms/inspect/order/WriteOrdertest.vue

@@ -0,0 +1,354 @@
+<template>
+  <ContentWrap>
+    <el-tabs v-model="activeTab" type="border-card" tab-position="left" v-loading="loading" style="height: 80vh">
+      <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(tab.deviceId) }}/{{ JSON.parse(tab.itemJson).length }})
+          </span>
+        </template>
+
+        <div class="step-container">
+          <el-steps
+            direction="vertical"
+            :active="currentStep[tab.deviceId]"
+            class="steps-nav"
+          >
+            <el-step
+              v-for="(step, stepIndex) in JSON.parse(tab.itemJson)"
+              :key="stepIndex"
+              :title="`${step.item}`"
+              :status="getStepStatus(tab.deviceId, stepIndex)"
+            >
+              <!--              <template #description>-->
+              <!--                <div class="step-content">-->
+              <!--                  <el-tooltip-->
+              <!--                    effect="dark"-->
+              <!--                    placement="top"-->
+              <!--                    :content="step.standard"-->
+              <!--                  >-->
+              <!--                    <Icon icon="ep:info-filled"/>-->
+              <!--                  </el-tooltip>-->
+              <!--                </div>-->
+              <!--              </template>-->
+              <template #title>
+                <div class="step-title-wrapper">
+                  <span class="title-text">{{ step.item }}</span>
+                  <el-tooltip
+                    :content="step.standard"
+                    placement="top"
+                    effect="dark"
+                  >
+                    <!--                    <el-icon class="tip-icon"/>-->
+                    <Icon icon="ep:info-filled"/>
+                  </el-tooltip>
+                </div>
+              </template>
+            </el-step>
+          </el-steps>
+
+          <div class="form-wrapper">
+            <el-form
+              :model="formData[tab.deviceId][currentStep[tabIndex]]"
+              :rules="formRules"
+              ref="formRefs"
+              label-width="120px"
+            >
+              <el-form-item label="是否异常" prop="ifNormal">
+                <el-select
+                  v-model="formData[tab.deviceId][currentStep[tabIndex]].ifNormal"
+                  placeholder="请选择是否异常"
+                  clearable
+                >
+                  <el-option
+                    v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
+                    :key="dict.value"
+                    :label="dict.label"
+                    :value="dict.value"
+                  />
+                </el-select>
+              </el-form-item>
+
+              <el-form-item label="异常描述" prop="description">
+                <el-input
+                  v-model="formData[tab.deviceId][currentStep[tabIndex]].description"
+                  :min="0"
+                  type="textarea"
+                  controls-position="right"
+                  placeholder="请填写异常描述"
+                />
+              </el-form-item>
+
+              <el-form-item label="图片" prop="picUrl">
+                <UploadImg v-model="formData[tab.deviceId][currentStep[tabIndex]].picUrl" height="55px" width="30em" />
+              </el-form-item>
+            </el-form>
+
+            <div class="navigation-controls">
+              <el-button
+                :disabled="currentStep[tabIndex] === 0"
+                @click="handlePrev(tabIndex)"
+              >
+                上一步
+              </el-button>
+
+              <el-button
+                type="primary"
+                :disabled="!isStepValid(tab.deviceId,tabIndex)"
+                @click="handleNext(tab.deviceId,tabIndex)"
+              >
+                {{ isLastStep(tabIndex) ? '完成提交' : '下一步' }}
+              </el-button>
+            </div>
+          </div>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+  </ContentWrap>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage } from 'element-plus'
+import {IotInspectOrderApi} from "@/api/pms/inspect/order";
+import {DICT_TYPE, getBoolDictOptions} from "@/utils/dict";
+
+const tabs = ref([])
+const { params, name } = useRoute() // 查询参数
+const id = params.id
+onMounted(async () => {
+  if (id) {
+    const iotInspectOrder = await IotInspectOrderApi.getIotInspectOrder(id)
+    tabs.value = JSON.parse(iotInspectOrder.deviceIds)
+    debugger
+    initFormData(JSON.parse(iotInspectOrder.deviceIds))
+    loading.value = false
+  }
+})
+
+// 响应式状态
+const loading = ref(true)
+const activeTab = ref('0')
+const currentStep = ref({})
+const formRefs = ref([])
+const formData = reactive([])
+
+// 表单验证规则
+const formRules = reactive({
+  ifNormal: [
+    { required: true, message: '请输入是否异常', trigger: 'blur' }
+  ],
+  description: [
+    { required: true, message: '请输入异常描述', trigger: 'blur' },
+  ],
+
+})
+
+// 初始化表单数据
+const initFormData = (tabsData) => {
+  tabsData.forEach((tab, tabIndex) => {
+    formData[tab.deviceId] = JSON.parse(tab.itemJson).map(() => ({
+      ifNormal: '',
+      description: null,
+      picUrl: ''
+    }))
+    currentStep.value[tabIndex] = 0
+  })
+}
+
+// 获取数据
+const fetchData = async () => {
+  try {
+    const data = await mockApi()
+    tabs.value = data
+    initFormData(data)
+  } catch (error) {
+    ElMessage.error('数据加载失败')
+  } finally {
+  }
+}
+
+// 步骤状态计算
+const getStepStatus = (tabIndex, stepIndex) => {
+  if (stepIndex < currentStep.value[tabIndex]) return 'finish'
+  return stepIndex === currentStep.value[tabIndex] ? 'process' : 'wait'
+}
+
+// 完成步骤数计算
+const completedSteps = (tabIndex) => {
+  return formData[tabIndex].filter(item =>
+    item.ifNormal && item.description !== null
+  ).length
+}
+
+// 步骤验证
+const isStepValid = (deviceId,tabIndex) => {
+  const current = currentStep.value[tabIndex]
+  debugger
+  return formData[deviceId][current].ifNormal!==null &&
+    formData[deviceId][current].description !== null&&formData[deviceId][current].description !== ''
+}
+
+// 导航控制
+const handlePrev = (tabIndex) => {
+  if (currentStep.value[tabIndex] > 0) {
+    currentStep.value[tabIndex]--
+  }
+}
+
+const handleNext = async (deviceId,tabIndex) => {
+  if (!isStepValid(deviceId,tabIndex)) {
+    return ElMessage.warning('请先完成当前步骤的必填项')
+  }
+
+  const totalSteps = JSON.parse(tabs.value[tabIndex].itemJson).length
+  debugger
+  if (currentStep.value[tabIndex] < totalSteps - 1) {
+    currentStep.value[tabIndex]++
+  } else {
+    await submitForm(tabIndex)
+  }
+}
+
+const isLastStep = (tabIndex) => {
+  return currentStep.value[tabIndex] === JSON.parse(tabs.value[tabIndex].itemJson).length - 1
+}
+
+// 提交表单
+const submitForm = async (tabIndex) => {
+  try {
+    debugger
+    // 这里添加实际提交逻辑
+    ElMessage.success(`提交成功:${tabs.value[tabIndex].deviceName}`)
+  } catch (error) {
+    ElMessage.error('提交失败,请检查数据')
+  }
+}
+
+</script>
+
+<style scoped>
+.container {
+  padding: 10px;
+  background: #f5f7fa;
+}
+
+.step-container {
+  display: grid;
+  grid-template-columns: 220px 1fr;
+  gap: 10px;
+  height: 100%;
+  min-height: 600px;
+}
+
+.steps-nav {
+  overflow-y: auto;
+  padding-right: 15px;
+}
+
+.form-wrapper {
+  background: #fff;
+  padding: 30px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px rgba(0,0,0,0.1);
+}
+
+.navigation-controls {
+  margin-top: 40px;
+  text-align: center;
+}
+
+.custom-label {
+  font-weight: 500;
+  padding: 0 15px;
+}
+::v-deep .el-step__icon {
+  background-color: #409eff;
+  color: #fff;
+  border: 0px;
+}
+.el-step__title {
+  font-size: 14px;
+}
+
+.el-form-item {
+  margin-bottom: 22px;
+}
+.hint-icon {
+  color: #909399;
+  font-size: 14px;
+  cursor: help;
+  transition: color 0.2s;
+
+  &:hover {
+    color: #409eff;
+  }
+}
+.step-content {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  gap: 5px;
+}
+
+
+
+.step-title-wrapper {
+  display: inline-flex;
+  align-items: center;
+  gap: 8px;
+  position: relative;
+  padding-right: 25px;
+}
+
+/* 提示图标样式 */
+.tip-icon {
+  font-size: 16px;
+  color: #e6a23c;
+  cursor: help;
+  transition:
+    color 0.3s ease,
+    transform 0.2s ease;
+
+  &:hover {
+    color: #f56c6c;
+    transform: scale(1.1);
+  }
+}
+
+/* 覆盖步骤条默认样式 */
+:deep(.custom-steps) {
+  /* 调整头部位置 */
+  .el-step__head {
+    top: 3px;
+  }
+
+  /* 标题容器定位 */
+  .el-step__title {
+    display: inline-block;
+    margin-left: 10px;
+    padding-right: 0;
+  }
+
+  /* 步骤连接线 */
+  .el-step__line {
+    left: 11px;
+    background-color: #ebeef5;
+  }
+
+  /* 当前步骤样式 */
+  .is-process .title-text {
+    font-weight: 600;
+    color: #409eff;
+  }
+
+  /* 完成状态图标 */
+  .is-finish .tip-icon {
+    color: #67c23a;
+  }
+}
+</style>