ソースを参照

Merge remote-tracking branch 'origin/master'

lipenghui 2 ヶ月 前
コミット
847da98248

+ 2 - 0
package.json

@@ -64,9 +64,11 @@
     "markmap-view": "^0.16.0",
     "min-dash": "^4.1.1",
     "mitt": "^3.0.1",
+    "moment": "^2.30.1",
     "nprogress": "^0.2.0",
     "pinia": "^2.1.7",
     "pinia-plugin-persistedstate": "^3.2.1",
+    "pinyin": "^4.0.0",
     "qrcode": "^1.5.3",
     "qs": "^6.12.0",
     "sortablejs": "1.15.0",

+ 8 - 0
src/api/pms/iotopeationfill/index.ts

@@ -39,10 +39,18 @@ export const IotOpeationFillApi = {
     return await request.get({ url: `/rq/iot-opeation-fill/page`, params })
   },
 
+  getIotOrderPage: async (params: any) => {
+    return await request.get({ url: `/rq/iot-opeation-fill/orderPage`, params })
+  },
+
   getIotOpeationFillPage1: async (params: any) => {
     return await request.get({ url: `/rq/iot-opeation-fill/page1`, params })
   },
 
+  getFillRecordsPage: async (params: any) => {
+    return await request.get({ url: `/rq/iot-opeation-fill/fillRecordPage`, params })
+  },
+
   getAttrs:async (params: any) => {
     return await request.get({ url: `/rq/iot-opeation-fill/getAttrs`, params })
   },

+ 1 - 0
src/utils/dict.ts

@@ -271,4 +271,5 @@ export enum DICT_TYPE {
   PMS_MAIN_WORK_ORDER_RESULT = 'pms_main_work_order_result', // 保养工单状态
   RQ_IOT_ISCOLLECTION = 'rq_iot_isCollection',//是否数采
   PMS_ORDER_PROCESS_MODE = "pms_main_work_order_process_mode",  // 保养方式 0内部保养  1委外保养
+  PMS_THING_MODEL_UNIT = 'pms_thing_model_unit', // pms属性模板单位
 }

+ 4 - 4
src/views/pms/bom/index.vue

@@ -90,8 +90,8 @@
             </template>
           </el-table-column>
           <el-table-column prop="deviceCategoryName" label="设备分类" />
-          <el-table-column prop="sort" label="排序" />
-          <el-table-column prop="status" label="状态" >
+          <el-table-column prop="sort" label="排序" width="80"/>
+          <el-table-column prop="status" label="状态" width="80">
             <template #default="scope">
               <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
             </template>
@@ -103,8 +103,8 @@
             prop="createTime"
             :formatter="dateFormatter"
           /> -->
-          <el-table-column prop="materials" label="物料数量" />
-          <el-table-column label="操作" align="center" >
+          <el-table-column prop="materials" label="物料数量" width="80"/>
+          <el-table-column label="操作" align="center" width="300">
             <template #default="scope">
               <el-button
                 link

+ 0 - 20
src/views/pms/device/DevicePerson.vue

@@ -128,26 +128,6 @@
           </el-table-column>
           <el-table-column label="所在部门" align="center" prop="deptName" />
           <el-table-column label="责任人" align="center" prop="responsibleNames" />
-          <el-table-column
-            label="创建时间"
-            align="center"
-            prop="createTime"
-            :formatter="dateFormatter"
-            width="180px"
-          />
-          <!-- <el-table-column label="操作" align="center" min-width="120px">
-             <template #default="scope">
-
-              <el-button
-                link
-                type="primary"
-                @click="openForm('update', scope.row.id)"
-                v-hasPermi="['rq:iot-device:update']"
-              >
-                编辑
-              </el-button>
-            </template>
-          </el-table-column> -->
         </el-table>
         <!-- 分页 -->
         <Pagination

+ 17 - 2
src/views/pms/devicetemplate/DeviceCategoryTree.vue

@@ -6,7 +6,7 @@
       </template>
     </el-input>
   </div>
-  <div class="head-container">
+  <div ref="treeContainer" class="tree-container">
     <el-tree
       ref="treeRef"
       :data="deviceCategoryList"
@@ -19,7 +19,7 @@
       node-key="id"
       @node-click="handleNodeClick"
       @node-contextmenu="handleRightClick"
-      style="height: 35em"
+      style="height: 52em"
     />
   </div>
   <div
@@ -104,6 +104,14 @@ watch(deviceCategoryName, (val) => {
   treeRef.value!.filter(val)
 })
 
+const treeContainer = ref(null)
+const setHeight = () => {
+  if (!treeContainer.value) return
+  const windowHeight = window.innerHeight
+  const containerTop = treeContainer.value.offsetTop
+  treeContainer.value.style.height = `${windowHeight * 0.78}px` // 60px 底部预留
+}
+
 /** 初始化 */
 onMounted(async () => {
   await getTree()
@@ -129,4 +137,11 @@ onMounted(async () => {
 .custom-menu li:hover {
   background: #f5f5f5;
 }
+
+.tree-container {
+  overflow-y: auto;
+  min-width: 100%;
+  border: 1px solid #e4e7ed;
+  border-radius: 4px;
+}
 </style>

+ 77 - 4
src/views/pms/devicetemplate/detail/attrsModel/AttrTemplateModelForm.vue

@@ -9,10 +9,12 @@
       label-width="100px"
     >
       <el-form-item label="属性名称" prop="name">
-        <el-input v-model="formData.name" placeholder="请输入属性名称" />
+        <el-input v-model="formData.name" placeholder="请输入属性名称"
+                  @compositionstart="handleCompositionStart"
+                  @compositionend="handleCompositionEnd"/>
       </el-form-item>
-      <el-form-item label="标识符" prop="code">
-        <el-input v-model="formData.code" placeholder="请输入标识符" />
+      <el-form-item label="标识符" prop="code" >
+        <el-input v-model="formData.code" placeholder="请输入标识符" disabled/>
       </el-form-item>
       <!-- 属性配置 -->
       <DeviceAttrModelProperty
@@ -43,7 +45,8 @@
 import DeviceAttrModelProperty from './AttrTemplateModelProperty.vue'
 import { DeviceAttrModelApi, DeviceAttrModelData } from '@/api/pms/deviceattrmodel'
 import { DataSpecsDataType, DeviceAttrModelFormRules } from './config'
-import { cloneDeep } from 'lodash-es'
+import pinyin from 'pinyin'
+import { cloneDeep, debounce } from 'lodash-es'
 import { isEmpty } from '@/utils/is'
 import { defineProps } from 'vue'
 
@@ -57,11 +60,26 @@ const dialogVisible = ref(false) // 弹窗的是否展示
 const dialogTitle = ref('') // 弹窗的标题
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const isComposing = ref(false)
+
+// 处理输入法开始事件
+const handleCompositionStart = () => {
+  isComposing.value = true
+}
+
+// 处理输入法结束事件
+const handleCompositionEnd = (event: CompositionEvent) => {
+  isComposing.value = false
+  // 手动触发处理
+  generateIdentifier((event.target as HTMLInputElement).value)
+}
+
 const formData = ref<DeviceAttrModelData>({
   deviceCategoryId: -1,
   dataType: DataSpecsDataType.DOUBLE,
   type: DataSpecsDataType.DOUBLE,
   requiredFlag: 0,
+  code: '',
   description: '',
   defaultValue: '',
   selectOptions: {
@@ -151,11 +169,61 @@ const removeDataSpecs = (val: any) => {
   }
 }
 
+// 处理属性名称生成标识符
+const processInputName = (name: string) => {
+  let result = ''
+  for (const char of name) {
+    // 汉字转拼音首字母
+    if (/[\u4e00-\u9fa5]/.test(char)) {
+      const pinyinArray = pinyin(char, {
+        style: pinyin.STYLE_FIRST_LETTER
+      })
+      if (pinyinArray[0]?.[0]) {
+        result += pinyinArray[0][0].toUpperCase()
+      }
+    }
+    // 非汉字字符原样保留
+    else {
+      result += char
+    }
+  }
+  return result
+}
+
+// 中文首字母提取方法
+const getChineseInitials = (name: string) => {
+  const chineseChars = name.match(/[\u4e00-\u9fa5]/g) || []
+  if (chineseChars.length === 0) return ''
+
+  const pinyinArray = pinyin(chineseChars.join(''), {
+    style: pinyin.STYLE_FIRST_LETTER,
+  })
+  return pinyinArray.map(arr => arr[0]?.charAt(0).toUpperCase()).join('')
+}
+
+// 生成标识符方法
+const generateIdentifier = debounce((name: string) => {
+  /* if (formData.value.code)  return */
+
+  const initials = processInputName(name)
+  if (initials) {
+    formData.value.code = `${initials}_${Date.now()}`
+  }
+}, 800)
+
+// 监听属性名称变化
+watchEffect(() => {
+  if (formData.value.name && !isComposing.value) {
+    generateIdentifier(formData.value.name)
+  }
+})
+
 /** 重置表单 */
 const resetForm = () => {
   formData.value = {
     dataType: DataSpecsDataType.DOUBLE,
     type: DataSpecsDataType.DOUBLE,
+    code: '',
     selectOptions: {
       type: DataSpecsDataType.DOUBLE,
       dataSpecs: {
@@ -165,4 +233,9 @@ const resetForm = () => {
   }
   formRef.value?.resetFields()
 }
+
+onMounted(async () => {
+  // 如果不修改 属性名称 不要自动生成新标识符
+  isComposing.value = true
+})
 </script>

+ 1 - 1
src/views/pms/devicetemplate/detail/dataSpecs/DeviceAttrModelNumberDataSpecs.vue

@@ -51,7 +51,7 @@
       @change="unitChange"
     >
       <el-option
-        v-for="(item, index) in getStrDictOptions(DICT_TYPE.IOT_THING_MODEL_UNIT)"
+        v-for="(item, index) in getStrDictOptions(DICT_TYPE.PMS_THING_MODEL_UNIT)"
         :key="index"
         :label="item.label"
         :value="item.label + '-' + item.value"

+ 5 - 5
src/views/pms/iotlockstock/IotAddToStock.vue

@@ -12,7 +12,7 @@
         <el-row>
           <el-col :span="8">
             <el-form-item label="工厂" prop="factoryId">
-              <el-select v-model="formData.factoryId" clearable placeholder="请选择工厂" class="!w-240px" @change="selectedFactoryChange">
+              <el-select v-model="formData.factoryId" clearable placeholder="请选择工厂" class="!w-240px" @change="selectedFactoryChange" disabled>
                 <el-option
                   v-for="item in factoryList"
                   :key="item.id"
@@ -24,7 +24,7 @@
           </el-col>
           <el-col :span="8">
             <el-form-item label="成本中心" prop="costCenterId">
-              <el-select v-model="formData.costCenterId" clearable placeholder="请选择成本中心" class="!w-240px">
+              <el-select v-model="formData.costCenterId" clearable placeholder="请选择成本中心" class="!w-240px" disabled>
                 <el-option
                   v-for="item in costCenterList"
                   :key="item.id"
@@ -170,8 +170,8 @@ const formData = ref({
 })
 
 const formRules = reactive({
-  factoryId: [{ required: true, message: '工厂不能为空', trigger: 'blur' }],
-  costCenterId: [{ required: true, message: '成本中心不能为空', trigger: 'blur' }],
+  // factoryId: [{ required: true, message: '工厂不能为空', trigger: 'blur' }],
+  // costCenterId: [{ required: true, message: '成本中心不能为空', trigger: 'blur' }],
 })
 
 // 多选 物料
@@ -206,7 +206,7 @@ const submitForm = async () => {
     return
   }
   if (formData.value.costCenterId === undefined) {
-    message.error('请选择成本中心')
+    message.error('请维护部门的成本中心')
     return
   }
   if (toRaw(list.value).length == 0) {

+ 2 - 1
src/views/pms/iotlockstock/index.vue

@@ -110,6 +110,7 @@
         :formatter="dateFormatter"
         width="180px"
       />
+      <!--
       <el-table-column label="操作" align="center" min-width="120px">
         <template #default="scope">
           <el-button
@@ -121,7 +122,7 @@
             编辑
           </el-button>
         </template>
-      </el-table-column>
+      </el-table-column> -->
     </el-table>
     <!-- 分页 -->
     <Pagination

+ 254 - 177
src/views/pms/iotmainworkorder/IotMainWorkOrder.vue

@@ -33,10 +33,18 @@
             -->
           </el-col>
           <el-col :span="8">
+            <el-form-item label="保养费用" prop="cost">
+              <el-input
+                v-model="formData.cost"
+                placeholder="根据物料消耗自动生成"
+                disabled
+              />
+            </el-form-item>
+            <!--
             <el-form-item label="责任人" prop="devicePersons">
               <el-input type="text" v-model="formData.devicePersons"  disabled/>
             </el-form-item>
-            <!--
+
             <el-form-item label="责任人" prop="responsiblePerson">
               <el-select v-model="formData.responsiblePerson" filterable clearable style="width: 100%">
                 <el-option
@@ -71,20 +79,6 @@
               />
             </el-form-item>
           </el-col>
-          <el-col :span="8">
-            <el-form-item label="保养费用" prop="cost">
-              <el-input
-                v-model="formData.cost"
-                placeholder="根据物料消耗自动生成"
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="16">
-            <el-form-item label="备注" prop="remark">
-              <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
-            </el-form-item>
-          </el-col>
           <el-col :span="8">
             <el-form-item label="其他费用" prop="otherCost">
               <el-input
@@ -94,6 +88,11 @@
               />
             </el-form-item>
           </el-col>
+          <el-col :span="24">
+            <el-form-item label="备注" prop="remark">
+              <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
+            </el-form-item>
+          </el-col>
         </el-row>
       </div>
     </el-form>
@@ -214,6 +213,12 @@
     <ContentWrap>
       <el-table v-loading="false" :data="materialList" :stripe="true" :show-overflow-tooltip="true" v-if="false">
         <el-table-column label="bom节点" align="center" prop="bomNodeId" />
+        <el-table-column label="工厂id" align="center" prop="factoryId" v-if="false"/>
+        <el-table-column label="工厂名称" align="center" prop="factory" v-if="false"/>
+        <el-table-column label="成本中心id" align="center" prop="costCenterId" v-if="false"/>
+        <el-table-column label="成本中心名称" align="center" prop="costCenter" v-if="false"/>
+        <el-table-column label="库存地点id" align="center" prop="storageLocationId" v-if="false"/>
+        <el-table-column label="库存地点名称" align="center" prop="projectDepartment" v-if="false"/>
         <el-table-column label="物料编码" align="center" prop="materialCode" />
         <el-table-column label="物料名称" align="center" prop="materialName" />
         <el-table-column label="单位" align="center" prop="unit" />
@@ -238,166 +243,208 @@
     :title="`设备 ${configDialog.current?.deviceCode+'-'+configDialog.current?.name} 保养配置`"
     width="600px"
   >
+    <!-- 使用header插槽自定义标题 -->
+    <template #header>
+      <span>设备 <strong>{{ configDialog.current?.deviceCode }}-{{ configDialog.current?.name }}</strong> 保养项配置</span>
+    </template>
     <el-form :model="configDialog.form" label-width="200px" :rules="configFormRules" ref="configFormRef">
-      <!-- 里程配置 -->
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="上次保养里程数(KM)"
-        prop="lastRunningKilometers"
-      >
-        <el-input-number
-          v-model="configDialog.form.lastRunningKilometers"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <!-- 推迟公里数 -->
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="推迟公里数(KM)"
-        prop="delayKilometers"
-      >
-        <el-input-number
-          v-model="configDialog.form.delayKilometers"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <!-- 运行时间配置 -->
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="上次保养运行时间(H)"
-        prop="lastRunningTime"
-      >
-        <el-input-number
-          v-model="configDialog.form.lastRunningTime"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <!-- 推迟时长 -->
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="推迟时长(H)"
-        prop="delayDuration"
-      >
-        <el-input-number
-          v-model="configDialog.form.delayDuration"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <!-- 自然日期配置 -->
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="上次保养自然日期(D)"
-        prop="lastNaturalDate"
-      >
-        <el-date-picker
-          v-model="configDialog.form.lastNaturalDate"
-          type="date"
-          placeholder="选择日期"
-          format="YYYY-MM-DD"
-          value-format="YYYY-MM-DD"
-          :disabled="true"
-        />
-      </el-form-item>
-      <!-- 推迟自然日期 -->
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="推迟自然日期(D)"
-        prop="delayNaturalDate"
-      >
-        <el-input-number
-          v-model="configDialog.form.delayNaturalDate"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <!-- 保养规则周期值 + 提前量 -->
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="运行里程周期(KM)"
-        prop="nextRunningKilometers"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextRunningKilometers"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="运行里程周期-提前量(KM)"
-        prop="kiloCycleLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.kiloCycleLead"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="运行时间周期(H)"
-        prop="nextRunningTime"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextRunningTime"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="运行时间周期-提前量(H)"
-        prop="timePeriodLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.timePeriodLead"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="自然日周期(D)"
-        prop="nextNaturalDate"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextNaturalDate"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="自然日周期-提前量(D)"
-        prop="naturalDatePeriodLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.naturalDatePeriodLead"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
+      <div class="form-group">
+        <div class="group-title">基础保养记录</div>
+        <!-- 里程配置 -->
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="上次保养里程数(KM)"
+          prop="lastRunningKilometers"
+        >
+          <el-input-number
+            v-model="configDialog.form.lastRunningKilometers"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <!-- 推迟公里数 -->
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="推迟公里数(KM)"
+          prop="delayKilometers"
+        >
+          <el-input-number
+            v-model="configDialog.form.delayKilometers"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+        <!-- 运行时间配置 -->
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="上次保养运行时间(H)"
+          prop="lastRunningTime"
+        >
+          <el-input-number
+            v-model="configDialog.form.lastRunningTime"
+            :precision="1"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <!-- 推迟时长 -->
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="推迟时长(H)"
+          prop="delayDuration"
+        >
+          <el-input-number
+            v-model="configDialog.form.delayDuration"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+        <!-- 自然日期配置 -->
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="上次保养自然日期"
+          prop="lastNaturalDate"
+        >
+          <el-date-picker
+            v-model="configDialog.form.lastNaturalDate"
+            type="date"
+            placeholder="选择日期"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <!-- 推迟自然日期 -->
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="推迟自然日期(D)"
+          prop="delayNaturalDate"
+        >
+          <el-input-number
+            v-model="configDialog.form.delayNaturalDate"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.mileageRule === 0">
+        <div class="group-title">运行里程规则配置</div>
+        <!-- 保养规则周期值 + 提前量 -->
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="运行里程周期(KM)"
+          prop="nextRunningKilometers"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextRunningKilometers"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="运行里程周期-提前量(KM)"
+          prop="kiloCycleLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.kiloCycleLead"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.runningTimeRule === 0">
+        <div class="group-title">运行时间规则配置</div>
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="运行时间周期(H)"
+          prop="nextRunningTime"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextRunningTime"
+            :precision="1"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="运行时间周期-提前量(H)"
+          prop="timePeriodLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.timePeriodLead"
+            :precision="1"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.naturalDateRule === 0">
+        <div class="group-title">自然日规则配置</div>
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="自然日周期(D)"
+          prop="nextNaturalDate"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextNaturalDate"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="自然日周期-提前量(D)"
+          prop="naturalDatePeriodLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.naturalDatePeriodLead"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+      </div>
     </el-form>
     <template #footer>
       <el-button @click="configDialog.visible = false">取消</el-button>
@@ -556,10 +603,13 @@ const selectChoose = (selectedMaterial) => {
 
   // 避免重复添加
   processedMaterials.forEach(newMaterial => {
-    // 检查是否已存在相同 bomNodeId + materialCode 的条目
+    // 检查是否已存在相同 工厂+成本中心+库存地点+bomNodeId + materialCode 的条目
     const isExist = materialList.value.some(item =>
       item.bomNodeId === bomNodeId.value &&
-      item.materialCode === newMaterial.materialCode
+      item.materialCode === newMaterial.materialCode &&
+      item.factoryId === newMaterial.factoryId &&
+      item.costCenterId === newMaterial.costCenterId &&
+      item.storageLocationId === newMaterial.storageLocationId
     );
 
     if (!isExist) {
@@ -878,7 +928,7 @@ onMounted(async () => {
         lastNaturalDate: item.lastNaturalDate ? dayjs(item.lastNaturalDate).format('YYYY-MM-DD') : null
       }))
       // 同时查询所有设备的责任人
-      await getDevicePersons();
+      // await getDevicePersons();
     }
   } catch (error) {
     console.error('数据加载失败:', error)
@@ -892,4 +942,31 @@ onMounted(async () => {
   overflow: hidden; /* 隐藏溢出的内容 */
   transition: max-height 0.3s ease; /* 平滑过渡效果 */
 }
+
+:deep(.el-input-number .el-input__inner) {
+  text-align: left !important;
+  padding-left: 10px; /* 保持左侧间距 */
+}
+
+/* 分组容器样式 */
+.form-group {
+  position: relative;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  padding: 20px 15px 10px;
+  margin-bottom: 18px;
+  transition: border-color 0.2s;
+}
+
+/* 分组标题样式 */
+.group-title {
+  position: absolute;
+  top: -10px;
+  left: 20px;
+  background: white;
+  padding: 0 8px;
+  color: #606266;
+  font-size: 12px;
+  font-weight: 500;
+}
 </style>

+ 48 - 17
src/views/pms/iotmainworkorder/IotMainWorkOrderAdd.vue

@@ -31,12 +31,21 @@
               <el-input type="text" v-model="formData.orderNumber" disabled/>
             </el-form-item>
             -->
+
           </el-col>
           <el-col :span="8">
+            <el-form-item label="保养费用" prop="cost">
+              <el-input
+                v-model="formData.cost"
+                placeholder="根据物料消耗自动生成"
+                disabled
+              />
+            </el-form-item>
+            <!--
             <el-form-item label="责任人" prop="devicePersons">
               <el-input type="text" v-model="formData.devicePersons"  disabled/>
             </el-form-item>
-            <!--
+
             <el-form-item label="责任人" prop="responsiblePerson">
               <el-select v-model="formData.responsiblePerson" filterable clearable style="width: 100%" disabled>
                 <el-option
@@ -71,20 +80,6 @@
               />
             </el-form-item>
           </el-col>
-          <el-col :span="8">
-            <el-form-item label="保养费用" prop="cost">
-              <el-input
-                v-model="formData.cost"
-                placeholder="根据物料消耗自动生成"
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="16">
-            <el-form-item label="备注" prop="remark">
-              <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
-            </el-form-item>
-          </el-col>
           <el-col :span="8">
             <el-form-item label="其他费用" prop="otherCost">
               <el-input
@@ -94,6 +89,12 @@
               />
             </el-form-item>
           </el-col>
+          <el-col :span="24">
+            <el-form-item label="备注" prop="remark">
+              <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
+            </el-form-item>
+          </el-col>
+
         </el-row>
       </div>
     </el-form>
@@ -247,6 +248,10 @@
     :title="`设备 ${configDialog.current?.deviceCode+'-'+configDialog.current?.name} 保养配置`"
     width="600px"
   >
+    <!-- 使用header插槽自定义标题 -->
+    <template #header>
+      <span>设备 <strong>{{ configDialog.current?.deviceCode }}-{{ configDialog.current?.name }}</strong> 保养项配置</span>
+    </template>
     <el-form :model="configDialog.form" label-width="200px" :rules="configFormRules" ref="configFormRef">
       <!-- 里程配置 -->
       <el-form-item
@@ -613,7 +618,6 @@ const selectChoose = (selectedMaterial) => {
   });
 }
 
-
 const deviceChoose = async(selectedDevices) => {
   const newIds = selectedDevices.map(device => device.id)
   deviceIds.value = [...new Set([...deviceIds.value, ...newIds])]
@@ -669,7 +673,7 @@ const deviceChoose = async(selectedDevices) => {
     }
   })
   // 新增完设备后 查询现有设备-bom明细中 所有设备配置的负责人姓名 逗号分隔
-  await getDevicePersons();
+  // await getDevicePersons();
 }
 
 /** 查看已经选择的物料 并编辑 */
@@ -969,4 +973,31 @@ const handleDelete = async (str: string) => {
   overflow: hidden; /* 隐藏溢出的内容 */
   transition: max-height 0.3s ease; /* 平滑过渡效果 */
 }
+
+:deep(.el-input-number .el-input__inner) {
+  text-align: left !important;
+  padding-left: 10px; /* 保持左侧间距 */
+}
+
+/* 分组容器样式 */
+.form-group {
+  position: relative;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  padding: 20px 15px 10px;
+  margin-bottom: 18px;
+  transition: border-color 0.2s;
+}
+
+/* 分组标题样式 */
+.group-title {
+  position: absolute;
+  top: -10px;
+  left: 20px;
+  background: white;
+  padding: 0 8px;
+  color: #606266;
+  font-size: 12px;
+  font-weight: 500;
+}
 </style>

+ 231 - 161
src/views/pms/iotmainworkorder/IotMainWorkOrderDetail.vue

@@ -247,168 +247,211 @@
     :title="`设备 ${configDialog.current?.deviceCode+'-'+configDialog.current?.name} 保养配置`"
     width="600px"
   >
+    <!-- 使用header插槽自定义标题 -->
+    <template #header>
+      <span>设备 <strong>{{ configDialog.current?.deviceCode }}-{{ configDialog.current?.name }}</strong> 保养项配置</span>
+    </template>
     <el-form :model="configDialog.form" label-width="200px" :rules="configFormRules" ref="configFormRef">
-      <!-- 里程配置 -->
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="上次保养里程数(KM)"
-        prop="lastRunningKilometers"
-      >
-        <el-input-number
-          v-model="configDialog.form.lastRunningKilometers"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <!-- 推迟公里数 -->
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="推迟公里数(KM)"
-        prop="delayKilometers"
-      >
-        <el-input-number
-          v-model="configDialog.form.delayKilometers"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <!-- 运行时间配置 -->
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="上次保养运行时间(H)"
-        prop="lastRunningTime"
-      >
-        <el-input-number
-          v-model="configDialog.form.lastRunningTime"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <!-- 推迟时长 -->
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="推迟时长(H)"
-        prop="delayDuration"
-      >
-        <el-input-number
-          v-model="configDialog.form.delayDuration"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <!-- 自然日期配置 -->
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="上次保养自然日期(D)"
-        prop="lastNaturalDate"
-      >
-        <el-date-picker
-          v-model="configDialog.form.lastNaturalDate"
-          type="date"
-          placeholder="选择日期"
-          format="YYYY-MM-DD"
-          value-format="YYYY-MM-DD"
-          :disabled="true"
-        />
-      </el-form-item>
-      <!-- 推迟自然日期 -->
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="推迟自然日期(D)"
-        prop="delayNaturalDate"
-      >
-        <el-input-number
-          v-model="configDialog.form.delayNaturalDate"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <!-- 保养规则周期值 + 提前量 -->
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="运行里程周期(KM)"
-        prop="nextRunningKilometers"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextRunningKilometers"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="运行里程周期-提前量(KM)"
-        prop="kiloCycleLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.kiloCycleLead"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="运行时间周期(H)"
-        prop="nextRunningTime"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextRunningTime"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="运行时间周期-提前量(H)"
-        prop="timePeriodLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.timePeriodLead"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="自然日周期(D)"
-        prop="nextNaturalDate"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextNaturalDate"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="自然日周期-提前量(D)"
-        prop="naturalDatePeriodLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.naturalDatePeriodLead"
-          :min="0"
-          controls-position="right"
-          :disabled="true"
-        />
-      </el-form-item>
+      <div class="form-group">
+        <div class="group-title">基础保养记录</div>
+        <!-- 里程配置 -->
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="上次保养里程数(KM)"
+          prop="lastRunningKilometers"
+        >
+          <el-input-number
+            v-model="configDialog.form.lastRunningKilometers"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <!-- 推迟公里数 -->
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="推迟公里数(KM)"
+          prop="delayKilometers"
+        >
+          <el-input-number
+            v-model="configDialog.form.delayKilometers"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <!-- 运行时间配置 -->
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="上次保养运行时间(H)"
+          prop="lastRunningTime"
+        >
+          <el-input-number
+            v-model="configDialog.form.lastRunningTime"
+            :precision="1"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <!-- 推迟时长 -->
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="推迟时长(H)"
+          prop="delayDuration"
+        >
+          <el-input-number
+            v-model="configDialog.form.delayDuration"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <!-- 自然日期配置 -->
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="上次保养自然日期"
+          prop="lastNaturalDate"
+        >
+          <el-date-picker
+            v-model="configDialog.form.lastNaturalDate"
+            type="date"
+            placeholder="选择日期"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <!-- 推迟自然日期 -->
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="推迟自然日期(D)"
+          prop="delayNaturalDate"
+        >
+          <el-input-number
+            v-model="configDialog.form.delayNaturalDate"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.mileageRule === 0">
+        <div class="group-title">运行里程规则配置</div>
+        <!-- 保养规则周期值 + 提前量 -->
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="运行里程周期(KM)"
+          prop="nextRunningKilometers"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextRunningKilometers"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="运行里程周期-提前量(KM)"
+          prop="kiloCycleLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.kiloCycleLead"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.runningTimeRule === 0">
+        <div class="group-title">运行时间规则配置</div>
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="运行时间周期(H)"
+          prop="nextRunningTime"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextRunningTime"
+            :precision="1"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="运行时间周期-提前量(H)"
+          prop="timePeriodLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.timePeriodLead"
+            :precision="1"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.naturalDateRule === 0">
+        <div class="group-title">自然日规则配置</div>
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="自然日周期(D)"
+          prop="nextNaturalDate"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextNaturalDate"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="自然日周期-提前量(D)"
+          prop="naturalDatePeriodLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.naturalDatePeriodLead"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+            :disabled="true"
+          />
+        </el-form-item>
+      </div>
     </el-form>
     <template #footer>
       <el-button @click="configDialog.visible = false">取消</el-button>
@@ -874,4 +917,31 @@ onMounted(async () => {
   overflow: hidden; /* 隐藏溢出的内容 */
   transition: max-height 0.3s ease; /* 平滑过渡效果 */
 }
+
+:deep(.el-input-number .el-input__inner) {
+  text-align: left !important;
+  padding-left: 10px; /* 保持左侧间距 */
+}
+
+/* 分组容器样式 */
+.form-group {
+  position: relative;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  padding: 20px 15px 10px;
+  margin-bottom: 18px;
+  transition: border-color 0.2s;
+}
+
+/* 分组标题样式 */
+.group-title {
+  position: absolute;
+  top: -10px;
+  left: 20px;
+  background: white;
+  padding: 0 8px;
+  color: #606266;
+  font-size: 12px;
+  font-weight: 500;
+}
 </style>

+ 3 - 0
src/views/pms/iotmainworkorder/SelectedMaterialDrawer.vue

@@ -13,6 +13,9 @@
       <div v-loading="loading" style="height: 100%">
         <el-table :data="filteredMaterials" style="width: 100%">
           <el-table-column prop="bomNodeId" label="bom节点" width="180" v-if="false"/>
+          <el-table-column prop="factory" label="工厂" width="180" />
+          <el-table-column prop="costCenter" label="成本中心" width="180" />
+          <el-table-column prop="projectDepartment" label="库存地点" width="180" />
           <el-table-column prop="materialName" label="物料名称" width="180" />
           <el-table-column prop="materialCode" label="物料编码" width="180" />
           <el-table-column prop="unit" label="单位" width="180" />

+ 14 - 1
src/views/pms/iotmainworkorder/WorkOrderMaterial.vue

@@ -124,7 +124,7 @@
             <el-input
               v-model="scope.row.quantity"
               @click.stop=""
-              @focus="scope.$el.querySelector('input').focus()"
+              @focus="handleInputFocus(scope.row)"
             />
           </template>
         </el-table-column>
@@ -330,6 +330,19 @@ const toggleRow = (row) => {
   }
 }
 
+// 处理输入框焦点事件(自动选中当前行)
+const handleInputFocus = (row: WorkOrderBomMaterialApi.IotMainWorkOrderBomMaterialVO) => {
+  const getRowUniqueKey = (row) => {
+    return `${row.factoryId}_${row.costCenterId}_${row.storageLocationId}_${row.materialCode}`
+  }
+  const currentKey = getRowUniqueKey(row)
+  // 如果未选中则添加到选中列表
+  const exists = selectedRows.value.some(item => getRowUniqueKey(item) === currentKey)
+  if (!exists) {
+    selectedRows.value.push(row)
+  }
+}
+
 /** 搜索按钮操作 */
 const handleQuery = () => {
   queryParams.pageNo = 1

+ 10 - 22
src/views/pms/iotmainworkorder/index.vue

@@ -25,7 +25,7 @@
           class="!w-240px"
         >
           <el-option
-            v-for="dict in getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT)"
+            v-for="dict in resultOptions"
             :key="dict.value"
             :label="dict.label"
             :value="dict.value"
@@ -90,27 +90,6 @@
         </template>
       </el-table-column>
       <el-table-column label="负责人" align="center" prop="responsiblePersonName" />
-      <el-table-column
-        label="实际保养开始时间"
-        align="center"
-        prop="actualStartTime"
-        :formatter="dateFormatter"
-        width="180px"
-      />
-      <el-table-column
-        label="实际保养结束时间"
-        align="center"
-        prop="actualEndTime"
-        :formatter="dateFormatter"
-        width="180px"
-      />
-      <el-table-column
-        label="创建时间"
-        align="center"
-        prop="createTime"
-        :formatter="dateFormatter"
-        width="180px"
-      />
       <el-table-column label="操作" align="center" min-width="120px">
         <template #default="scope">
           <el-button
@@ -224,6 +203,15 @@ const resetQuery = () => {
   handleQuery()
 }
 
+// 保养状态 下拉列表 添加数据字典外的选项
+const resultOptions = computed(() => [
+  {
+    label: '全部',
+    value: '0' // 空值会触发 clearable 效果
+  },
+  ...getStrDictOptions(DICT_TYPE.PMS_MAIN_WORK_ORDER_RESULT)
+])
+
 /** 添加/修改操作 */
 const formRef = ref()
 const openForm = (type: string, id?: number) => {

+ 20 - 42
src/views/pms/iotopeationfill/index.vue

@@ -100,47 +100,25 @@
         />-->
         <el-table-column label="操作" align="center" min-width="120px">
           <template #default="scope">
-  <!--          <el-button-->
-  <!--            link-->
-  <!--            type="primary"-->
-  <!--            @click="openForm('update', scope.row.id)"-->
-  <!--            v-hasPermi="['rq:iot-inspect-order:update']"-->
-  <!--          >-->
-  <!--            编辑-->
-  <!--          </el-button>-->
-  <!--          <el-button-->
-  <!--            link-->
-  <!--            type="danger"-->
-  <!--            @click="handleDelete(scope.row.id)"-->
-  <!--            v-hasPermi="['rq:iot-inspect-order:delete']"-->
-  <!--          >-->
-  <!--            删除-->
-  <!--          </el-button>-->
-            <el-button
-              link
-              type="primary"
-              @click="openWrite(scope.row.deptId+','+scope.row.userId+','+scope.row.createTime+','+scope.row.id)"
-              v-hasPermi="['rq:iot-opeation-fill:update']"
-            >
-              填写
-            </el-button>
-            <el-button
-              link
-              type="primary"
-              @click="openWrite(scope.row.deptId+','+scope.row.userId+','+scope.row.createTime)"
-              v-if='scope.row.orderStatus === "已完成"'
-            >
-              查看
+              <el-button
+                link
+                type="primary"
+                @click="openWrite(scope.row.deptId+','+scope.row.userId+','+scope.row.createTime
+                +','+scope.row.id+','+scope.row.orderStatus)"
+                v-hasPermi="['rq:iot-opeation-fill:update']"
+                v-if="scope.row.orderStatus !== 1"
+              >
+                填写
+              </el-button>
+              <el-button
+                link
+                type="primary"
+                @click="openWrite(scope.row.deptId+','+scope.row.userId+','+scope.row.createTime+','+scope.row.id+','+scope.row.orderStatus)"
+                v-else
+              >
+                查看
+              </el-button>
 
-            </el-button>
-            <el-button
-              link
-              type="primary"
-              @click="openWrite(scope.row.deptId)"
-              v-else
-            >
-              查看
-            </el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -186,9 +164,9 @@ const queryParams = reactive({
   status: undefined,
   remark: undefined,
   createTime: [],
-  deptId: undefined,
+  deptId: useUserStore().getUser.deptId,
   deviceIds: undefined,
-  userId:useUserStore().getUser.id
+  //userId:useUserStore().getUser.id
 })
 const queryFormRef = ref() // 搜索的表单
 const exportLoading = ref(false) // 导出的加载中

+ 32 - 24
src/views/pms/iotopeationfill/index1.vue

@@ -33,22 +33,22 @@
                 <el-form-item :label='item.name' prop="deviceId"  >
                   <el-input
                     v-if="item.isCollection===1"
-                    v-model="item.fillContent" @input="attrList[index].fillContent = $event.target.fillContent"
+                    v-model="item.fillContent"
                     clearable
                     style="width: 200px"
                     disabled
                   />
                   <el-input
                     v-else
-                    v-model="item.fillContent" @input="attrList[index].fillContent = $event.target.fillContent"
+                    v-model="item.fillContent"
                     clearable
                     style="width: 200px"
                   />
                 </el-form-item>
             </div>
             <el-form-item>
-              <el-button type="info" @click="deleteFillInfo">取消</el-button>
-              <el-button type="primary" @click="getFillInfo">确定</el-button>
+              <el-button type="primary" @click="getFillInfo" v-show="showStatus">确定</el-button>
+              <el-button type="info" @click="deleteFillInfo" v-show="showStatus">取消</el-button>
             </el-form-item>
           </el-form>
         </div>
@@ -68,6 +68,7 @@ import {useUserStore} from "@/store/modules/user";
 import { ElMessage } from 'element-plus'
 import moment from 'moment';
 import { format } from 'date-fns';
+import {cx} from "@fullcalendar/core/internal-common";
 /** 运行记录填报 列表 */
 defineOptions({ name: 'IotOpeationFill' })
 
@@ -83,6 +84,8 @@ const attrList = ref<IotOpeationFillVO[]>([]) // 列表的数据
 const total = ref(0) // 列表的总页数
 const arry1 =ref([]);
 let totalRunTime1: string = '123'
+let fillStatus = params.id.split(",")[4];
+let showStatus = true;
 const queryParams = reactive({
   pageNo: 1,
   pageSize: 10,
@@ -101,16 +104,25 @@ const queryParams = reactive({
   creDate: [],
   createTime: [],
   deviceCategoryId:1,
+  deviceId:undefined
 })
 const queryFormRef = ref() // 搜索的表单
 const exportLoading = ref(false) // 导出的加载中
-
+let cxStatus = true;
 
 const formatDescription = async(row, column, cellValue) =>{
   return cellValue.split(',').map(part => `<div>${part}</div>`).join('');
 }
 
 
+
+const showComponent = () => {
+  if(JSON.parse(fillStatus)=== 1){
+    showStatus = false;
+  }
+};
+
+
 /** 查询列表 */
 const getList = async () => {
   loading.value = true
@@ -118,24 +130,19 @@ const getList = async () => {
     queryParams.deptId = deptId.split(",")[0];
     queryParams.userId = deptId.split(",")[1];
     queryParams.createTime = formatTimestamp(JSON.parse(deptId.split(",")[2].substring(0,10)));
-    const data = await IotOpeationFillApi.getIotOpeationFillPage(queryParams)
-    if(data.length===0){
-      ElMessage({
-        message: '改用户负责设备状态为非施工或待命,请调整',
-        type: 'warning',
-      })
-    }else{
+    queryParams.orderId = deptId.split(",")[3];
+    const data = await IotOpeationFillApi.getIotOpeationFillPage(queryParams);
       list.value = data;
-      list.value.forEach(function (item, index) {
-        arry1.value[index] = item;
-      });
-      queryParams.deviceCategoryId = arry1.value[0].deviceCategoryId
-      queryParams.deptId = arry1.value[0].deptId;
-      queryParams.deviceCode = arry1.value[0].deviceCode;
-      queryParams.deviceName = arry1.value[0].deviceName;
-      queryParams.deviceId = arry1.value[0].deviceId;
+      if(cxStatus){
+        queryParams.deviceCategoryId = list.value[0].deviceCategoryId
+        queryParams.deptId = list.value[0].deptId;
+        queryParams.deviceCode = list.value[0].deviceCode;
+        queryParams.deviceName = list.value[0].deviceName;
+        queryParams.deviceId = list.value[0].deviceId;
+      }
       getAttrList();
-    }
+
+
   } finally {
     loading.value = false
   }
@@ -168,6 +175,7 @@ const open = async (type: string, id?: number) => {
 }
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 const openFill = (deviceCategoryId?:number,deviceId?:number,deptId?:number,deviceName?:string,deviceCode?:string) =>{
+
   queryParams.deviceCategoryId = deviceCategoryId;
   queryParams.deptId = deptId;
   queryParams.deviceCode = deviceCode;
@@ -184,7 +192,6 @@ const getAttrList = async () => {
     queryParams.createTime = formatTimestamp(JSON.parse(deptId.split(",")[2].substring(0,10)));
     const data = await IotOpeationFillApi.getAttrs(queryParams)
     attrList.value = data;
-    //totalRunTime1 = Number(attrList.value[0].totalRunTime).toFixed(2)
     attrList.value.forEach(function (item,index){
 
       if(item.name==='累计运行时间'){
@@ -197,10 +204,10 @@ const getAttrList = async () => {
       item.deviceId = queryParams.deviceId;
       item.deviceCategoryId = queryParams.deviceCategoryId;
     })
-
   } finally {
     loading.value = false
   }
+
 }
 /** 获取填写信息保存到后台*/
 const getFillInfo = async () => {
@@ -216,6 +223,7 @@ const getFillInfo = async () => {
     message.success(t('common.createSuccess'))
     // 发送操作成功的事件
     emit('success')
+    cxStatus = false;
     getList();
   } finally {
 
@@ -260,7 +268,7 @@ const handleExport = async () => {
 /** 初始化 **/
 onMounted(() => {
   getList()
-
+  showComponent()
 })
 </script>
 <style scoped>

+ 0 - 2
src/views/pms/iotsapstock/IotConfigSafeStock.vue

@@ -51,8 +51,6 @@
         </el-table-column>
       </el-table>
     </ContentWrap>
-    <!--
-    <MaterialSelect ref="materialFormRef" @choose="materialChoose" /> -->
     <SelectSapStock ref="sapStockFormRef" @choose="stockChoose" />
   </ContentWrap>
   <ContentWrap>

+ 2 - 11
src/views/pms/iotsapstock/IotSapStockConfig.vue

@@ -99,6 +99,7 @@
         :formatter="dateFormatter"
         width="180px"
       />
+      <!--
       <el-table-column label="操作" align="center" min-width="120px">
         <template #default="scope">
           <el-button
@@ -110,18 +111,8 @@
           >
             安全库存
           </el-button>
-          <!--
-          <el-button
-            link
-            type="danger"
-            @click="handleDelete(scope.row.id)"
-            v-hasPermi="['pms:iot-sap-stock:delete']"
-          >
-            删除
-          </el-button>
-          -->
         </template>
-      </el-table-column>
+      </el-table-column> -->
     </el-table>
     <!-- 分页 -->
     <Pagination

+ 10 - 1
src/views/pms/iotsapstock/SelectSapStock.vue

@@ -75,7 +75,7 @@
               <el-input
                 v-model="scope.row.safetyStock"
                 @click.stop=""
-                @focus="scope.$el.querySelector('input').focus()"
+                @focus="handleInputFocus(scope.row)"
               />
             </template>
           </el-table-column>
@@ -186,6 +186,15 @@ const getList = async () => {
   }
 }
 
+// 处理输入框焦点事件(自动选中当前行)
+const handleInputFocus = (row: MaterialApi.MaterialVO) => {
+  // 如果未选中则添加到选中列表
+  const exists = selectedRows.value.some(item => item.id === row.id)
+  if (!exists) {
+    selectedRows.value.push(row)
+  }
+}
+
 /** 搜索按钮操作 */
 const handleQuery = () => {
   queryParams.pageNo = 1

+ 34 - 11
src/views/pms/iotsapstock/index.vue

@@ -57,6 +57,21 @@
           class="!w-220px"
         />
       </el-form-item>
+      <el-form-item label="是否配置安全库存" prop="configFlag" label-width="140px">
+        <el-select
+          v-model="queryParams.configFlag"
+          placeholder="请选择"
+          clearable
+          class="!w-240px"
+        >
+          <el-option
+            v-for="dict in resultOptions"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
       <el-form-item>
         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
@@ -99,6 +114,7 @@
         :formatter="dateFormatter"
         width="180px"
       />
+      <!--
       <el-table-column label="操作" align="center" min-width="120px">
         <template #default="scope">
           <el-button
@@ -110,18 +126,8 @@
           >
             安全库存
           </el-button>
-          <!--
-          <el-button
-            link
-            type="danger"
-            @click="handleDelete(scope.row.id)"
-            v-hasPermi="['pms:iot-sap-stock:delete']"
-          >
-            删除
-          </el-button>
-          -->
         </template>
-      </el-table-column>
+      </el-table-column> -->
     </el-table>
     <!-- 分页 -->
     <Pagination
@@ -180,6 +186,7 @@ const queryParams = reactive({
   sort: undefined,
   status: undefined,
   remark: undefined,
+  configFlag: 'A',
   createTime: [],
 })
 const queryFormRef = ref() // 搜索的表单
@@ -240,6 +247,22 @@ const selectedFactoryChange = async (selectedId: number | undefined) => {
   storageLocationList.value = await SapOrgApi.SapOrgApi.getSelectedList(selectedFactoryReqVO.value)
 }
 
+// 是否已经配置了安全库存 下拉列表 模拟字典项
+const resultOptions = computed(() => [
+  {
+    label: '全部',
+    value: 'A' // 空值会触发 clearable 效果
+  },
+  {
+    label: '是',
+    value: 'Y' // 空值会触发 clearable 效果
+  },
+  {
+    label: '否',
+    value: 'N' // 空值会触发 clearable 效果
+  },
+])
+
 /** 删除按钮操作 */
 const handleDelete = async (id: number) => {
   try {

+ 178 - 128
src/views/pms/maintenance/IotMaintenancePlan.vue

@@ -10,35 +10,22 @@
     >
       <div class="base-expandable-content">
         <el-row>
-          <el-col :span="8">
+          <el-col :span="12">
             <el-form-item label="计划名称" prop="name">
               <el-input type="text" v-model="formData.name" />
             </el-form-item>
           </el-col>
-          <el-col :span="8">
+          <el-col :span="12">
             <el-form-item label="计划编号" prop="serialNumber">
               <el-input type="text" v-model="formData.serialNumber" disabled/>
             </el-form-item>
           </el-col>
+          <!--
           <el-col :span="8">
             <el-form-item label="设备责任人" prop="devicePersons">
               <el-input type="text" v-model="formData.devicePersons"  disabled/>
             </el-form-item>
-          </el-col>
-          <!--
-          <el-col :span="8" >
-            <el-form-item label="责任人" prop="responsiblePerson" >
-              <el-select v-model="formData.responsiblePerson" filterable clearable style="width: 100%">
-                <el-option
-                  v-for="item in deptUsers"
-                  :key="item.id"
-                  :label="item.nickname"
-                  :value="item.id"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          -->
+          </el-col> -->
           <el-col :span="24">
             <el-form-item label="备注" prop="remark">
               <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
@@ -174,118 +161,154 @@
     :title="`设备 ${configDialog.current?.deviceCode+'-'+configDialog.current?.name} 保养配置`"
     width="600px"
   >
+    <!-- 使用header插槽自定义标题 -->
+    <template #header>
+      <span>设备 <strong>{{ configDialog.current?.deviceCode }}-{{ configDialog.current?.name }}</strong> 保养项配置</span>
+    </template>
     <el-form :model="configDialog.form" label-width="200px" :rules="configFormRules" ref="configFormRef">
-      <!-- 里程配置 -->
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="上次保养里程数(KM)"
-        prop="lastRunningKilometers"
-      >
-        <el-input-number
-          v-model="configDialog.form.lastRunningKilometers"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <!-- 运行时间配置 -->
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="上次保养运行时间(H)"
-        prop="lastRunningTime"
-      >
-        <el-input-number
-          v-model="configDialog.form.lastRunningTime"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <!-- 自然日期配置 -->
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="上次保养自然日期(D)"
-        prop="lastNaturalDate"
-      >
-        <el-date-picker
-          v-model="configDialog.form.lastNaturalDate"
-          type="date"
-          placeholder="选择日期"
-          format="YYYY-MM-DD"
-          value-format="YYYY-MM-DD"
-        />
-      </el-form-item>
-      <!-- 保养规则周期值 + 提前量 -->
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="运行里程周期(KM)"
-        prop="nextRunningKilometers"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextRunningKilometers"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="运行里程周期-提前量(KM)"
-        prop="kiloCycleLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.kiloCycleLead"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="运行时间周期(H)"
-        prop="nextRunningTime"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextRunningTime"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="运行时间周期-提前量(H)"
-        prop="timePeriodLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.timePeriodLead"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="自然日周期(D)"
-        prop="nextNaturalDate"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextNaturalDate"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="自然日周期-提前量(D)"
-        prop="naturalDatePeriodLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.naturalDatePeriodLead"
-          :min="0"
-          controls-position="right"
-        />
-      </el-form-item>
+      <div class="form-group">
+        <div class="group-title">基础保养记录</div>
+        <!-- 里程配置 -->
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="上次保养里程数(KM)"
+          prop="lastRunningKilometers"
+        >
+          <el-input-number
+            v-model="configDialog.form.lastRunningKilometers"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+        <!-- 运行时间配置 -->
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="上次保养运行时间(H)"
+          prop="lastRunningTime"
+        >
+          <el-input-number
+            v-model="configDialog.form.lastRunningTime"
+            :precision="1"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+        <!-- 自然日期配置 -->
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="上次保养自然日期"
+          prop="lastNaturalDate"
+        >
+          <el-date-picker
+            v-model="configDialog.form.lastNaturalDate"
+            type="date"
+            placeholder="选择日期"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            style="width: 60%"
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.mileageRule === 0">
+        <div class="group-title">运行里程规则配置</div>
+        <!-- 保养规则周期值 + 提前量 -->
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="运行里程周期(KM)"
+          prop="nextRunningKilometers"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextRunningKilometers"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="运行里程周期-提前量(KM)"
+          prop="kiloCycleLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.kiloCycleLead"
+            :precision="2"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.runningTimeRule === 0">
+        <div class="group-title">运行时间规则配置</div>
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="运行时间周期(H)"
+          prop="nextRunningTime"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextRunningTime"
+            :precision="1"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="运行时间周期-提前量(H)"
+          prop="timePeriodLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.timePeriodLead"
+            :precision="1"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.naturalDateRule === 0">
+        <div class="group-title">自然日规则配置</div>
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="自然日周期(D)"
+          prop="nextNaturalDate"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextNaturalDate"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="自然日周期-提前量(D)"
+          prop="naturalDatePeriodLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.naturalDatePeriodLead"
+            :min="0"
+            controls-position="right"
+            :controls="false"
+            style="width: 60%"
+          />
+        </el-form-item>
+      </div>
     </el-form>
     <template #footer>
       <el-button @click="configDialog.visible = false">取消</el-button>
@@ -835,4 +858,31 @@ const handleDelete = async (str: string) => {
   overflow: hidden; /* 隐藏溢出的内容 */
   transition: max-height 0.3s ease; /* 平滑过渡效果 */
 }
+
+:deep(.el-input-number .el-input__inner) {
+  text-align: left !important;
+  padding-left: 10px; /* 保持左侧间距 */
+}
+
+/* 分组容器样式 */
+.form-group {
+  position: relative;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  padding: 20px 15px 10px;
+  margin-bottom: 18px;
+  transition: border-color 0.2s;
+}
+
+/* 分组标题样式 */
+.group-title {
+  position: absolute;
+  top: -10px;
+  left: 20px;
+  background: white;
+  padding: 0 8px;
+  color: #606266;
+  font-size: 12px;
+  font-weight: 500;
+}
 </style>

+ 186 - 141
src/views/pms/maintenance/IotMaintenancePlanDetail.vue

@@ -10,16 +10,17 @@
     >
       <div class="base-expandable-content">
         <el-row>
-          <el-col :span="8">
+          <el-col :span="12">
             <el-form-item label="计划名称" prop="name">
               <el-input type="text" v-model="formData.name" disabled/>
             </el-form-item>
           </el-col>
-          <el-col :span="8">
+          <el-col :span="12">
             <el-form-item label="计划编号" prop="serialNumber">
               <el-input type="text" v-model="formData.serialNumber" disabled/>
             </el-form-item>
           </el-col>
+          <!--
           <el-col :span="8">
             <el-form-item label="责任人" prop="responsiblePerson">
               <el-select v-model="formData.responsiblePerson" filterable clearable style="width: 100%" disabled>
@@ -31,7 +32,7 @@
                 />
               </el-select>
             </el-form-item>
-          </el-col>
+          </el-col> -->
           <el-col :span="24">
             <el-form-item label="备注" prop="remark">
               <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" disabled/>
@@ -42,23 +43,6 @@
     </el-form>
   </ContentWrap>
   <ContentWrap>
-    <!--
-    <ContentWrap>
-       搜索工作栏
-      <el-form
-        class="-mb-15px"
-        :model="queryParams"
-        ref="queryFormRef"
-        :inline="true"
-        label-width="68px"
-      >
-        <el-form-item>
-          <el-button @click="openForm" type="warning">
-            <Icon icon="ep:plus" class="mr-5px" /> 新增设备</el-button>
-        </el-form-item>
-      </el-form>
-    </ContentWrap> -->
-
     <!-- 列表 -->
     <ContentWrap>
       <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
@@ -168,130 +152,164 @@
   <!-- 新增配置对话框 -->
   <el-dialog
     v-model="configDialog.visible"
-    :title="`设备 ${configDialog.current?.deviceCode+'-'+configDialog.current?.name} 保养配置`"
+    :title="`设备 ${configDialog.current?.deviceCode+'-'+configDialog.current?.name} 保养配置`"
     width="600px"
   >
+    <!-- 使用header插槽自定义标题 -->
+    <template #header>
+      <span>设备 <strong>{{ configDialog.current?.deviceCode }}-{{ configDialog.current?.name }}</strong> 保养项配置</span>
+    </template>
     <el-form :model="configDialog.form" label-width="200px" :rules="configFormRules" ref="configFormRef">
-      <!-- 里程配置 -->
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="上次保养里程数(KM)"
-        prop="lastRunningKilometers"
-      >
-        <el-input-number
-          v-model="configDialog.form.lastRunningKilometers"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          disabled
-        />
-      </el-form-item>
-      <!-- 运行时间配置 -->
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="上次保养运行时间(H)"
-        prop="lastRunningTime"
-      >
-        <el-input-number
-          v-model="configDialog.form.lastRunningTime"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-          disabled
-        />
-      </el-form-item>
-      <!-- 自然日期配置 -->
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="上次保养自然日期(D)"
-        prop="lastNaturalDate"
-      >
-        <el-date-picker
-          v-model="configDialog.form.lastNaturalDate"
-          type="date"
-          placeholder="选择日期"
-          format="YYYY-MM-DD"
-          value-format="YYYY-MM-DD"
-          disabled
-        />
-      </el-form-item>
-      <!-- 保养规则周期值 + 提前量 -->
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="运行里程周期(KM)"
-        prop="nextRunningKilometers"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextRunningKilometers"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          disabled
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.mileageRule === 0"
-        label="运行里程周期-提前量(KM)"
-        prop="kiloCycleLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.kiloCycleLead"
-          :precision="2"
-          :min="0"
-          controls-position="right"
-          disabled
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="运行时间周期(H)"
-        prop="nextRunningTime"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextRunningTime"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-          disabled
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.runningTimeRule === 0"
-        label="运行时间周期-提前量(H)"
-        prop="timePeriodLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.timePeriodLead"
-          :precision="1"
-          :min="0"
-          controls-position="right"
-          disabled
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="自然日周期(D)"
-        prop="nextNaturalDate"
-      >
-        <el-input-number
-          v-model="configDialog.form.nextNaturalDate"
-          :min="0"
-          controls-position="right"
-          disabled
-        />
-      </el-form-item>
-      <el-form-item
-        v-if="configDialog.current?.naturalDateRule === 0"
-        label="自然日周期-提前量(D)"
-        prop="naturalDatePeriodLead"
-      >
-        <el-input-number
-          v-model="configDialog.form.naturalDatePeriodLead"
-          :min="0"
-          controls-position="right"
-          disabled
-        />
-      </el-form-item>
+      <div class="form-group">
+        <div class="group-title">基础保养记录</div>
+        <!-- 里程配置 -->
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="上次保养里程数(KM)"
+          prop="lastRunningKilometers"
+        >
+          <el-input-number
+            v-model="configDialog.form.lastRunningKilometers"
+            :precision="2"
+            :controls="false"
+            controls-position="right"
+            style="width: 60%"
+            disabled
+          />
+        </el-form-item>
+        <!-- 运行时间配置 -->
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="上次保养运行时间(H)"
+          prop="lastRunningTime"
+        >
+          <el-input-number
+            v-model="configDialog.form.lastRunningTime"
+            :precision="1"
+            :controls="false"
+            controls-position="right"
+            style="width: 60%"
+            disabled
+          />
+        </el-form-item>
+        <!-- 自然日期配置 -->
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="上次保养自然日期"
+          prop="lastNaturalDate"
+        >
+          <el-date-picker
+            v-model="configDialog.form.lastNaturalDate"
+            type="date"
+            placeholder="选择日期"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            style="width: 60%"
+            disabled
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.mileageRule === 0">
+        <div class="group-title">运行里程规则配置</div>
+        <!-- 保养规则周期值 + 提前量 -->
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="运行里程周期(KM)"
+          prop="nextRunningKilometers"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextRunningKilometers"
+            :precision="2"
+            :min="0"
+            :controls="false"
+            controls-position="right"
+            style="width: 60%"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.mileageRule === 0"
+          label="运行里程周期-提前量(KM)"
+          prop="kiloCycleLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.kiloCycleLead"
+            :precision="2"
+            :min="0"
+            :controls="false"
+            controls-position="right"
+            style="width: 60%"
+            disabled
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.runningTimeRule === 0">
+        <div class="group-title">运行时间规则配置</div>
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="运行时间周期(H)"
+          prop="nextRunningTime"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextRunningTime"
+            :precision="1"
+            :min="0"
+            :controls="false"
+            controls-position="right"
+            style="width: 60%"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.runningTimeRule === 0"
+          label="运行时间周期-提前量(H)"
+          prop="timePeriodLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.timePeriodLead"
+            :precision="1"
+            :min="0"
+            :controls="false"
+            controls-position="right"
+            style="width: 60%"
+            disabled
+          />
+        </el-form-item>
+      </div>
+
+      <div class="form-group" v-if="configDialog.current?.naturalDateRule === 0">
+        <div class="group-title">自然日规则配置</div>
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="自然日周期(D)"
+          prop="nextNaturalDate"
+        >
+          <el-input-number
+            v-model="configDialog.form.nextNaturalDate"
+            :min="0"
+            :controls="false"
+            controls-position="right"
+            style="width: 60%"
+            disabled
+          />
+        </el-form-item>
+        <el-form-item
+          v-if="configDialog.current?.naturalDateRule === 0"
+          label="自然日周期-提前量(D)"
+          prop="naturalDatePeriodLead"
+        >
+          <el-input-number
+            v-model="configDialog.form.naturalDatePeriodLead"
+            :min="0"
+            :controls="false"
+            controls-position="right"
+            style="width: 60%"
+            disabled
+          />
+        </el-form-item>
+      </div>
     </el-form>
     <template #footer>
       <el-button @click="configDialog.visible = false">取消</el-button>
@@ -742,4 +760,31 @@ const handleDelete = async (str: string) => {
   overflow: hidden; /* 隐藏溢出的内容 */
   transition: max-height 0.3s ease; /* 平滑过渡效果 */
 }
+
+:deep(.el-input-number .el-input__inner) {
+  text-align: left !important;
+  padding-left: 10px; /* 保持左侧间距 */
+}
+
+/* 分组容器样式 */
+.form-group {
+  position: relative;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  padding: 20px 15px 10px;
+  margin-bottom: 18px;
+  transition: border-color 0.2s;
+}
+
+/* 分组标题样式 */
+.group-title {
+  position: absolute;
+  top: -10px;
+  left: 20px;
+  background: white;
+  padding: 0 8px;
+  color: #606266;
+  font-size: 12px;
+  font-weight: 500;
+}
 </style>