Jelajahi Sumber

Merge remote-tracking branch 'origin/master'

lipenghui 2 bulan lalu
induk
melakukan
9775a8e69a

+ 2 - 1
src/locales/en.ts

@@ -635,7 +635,8 @@ export default {
     rpHolder:'Please select the Department',
     reasonForAdjustment:'ReasonForAdjustment',
     rfaHolder:'Please enter reason',
-    adjustmentRecords:'AdjustmentRecords'
+    adjustmentRecords:'AdjustmentRecords',
+    selectPersons: 'Please select Person'
   },
   deviceStatus:{
     deviceName:'DeviceName',

+ 2 - 1
src/locales/zh-CN.ts

@@ -629,7 +629,8 @@ export default {
     rpHolder:'请选择所属部门',
     reasonForAdjustment:'调整原因',
     rfaHolder:'请输入调整原因',
-    adjustmentRecords:'调整记录'
+    adjustmentRecords:'调整记录',
+    selectPersons: '请选择责任人'
   },
   deviceStatus:{
     deviceName:'设备名称',

+ 129 - 13
src/views/pms/device/allotlog/ConfigDeviceAllot.vue

@@ -37,7 +37,7 @@
                 class="checkbox-item"
               >
                 <el-checkbox :label="device.id">
-                  {{ device.deviceCode }} ({{ device.deviceName }}) - {{ device.deptName }}
+                  {{ device.deviceCode }} ({{ device.deviceName }}) - {{ device.deptName }} —— {{ device.devicePersons }}
                 </el-checkbox>
               </div>
             </el-checkbox-group>
@@ -58,24 +58,56 @@
 
     <!-- 暂存关联列表 -->
     <div class="submit-area">
-      <div class="card">
-        <el-input
-          v-model="formData.reason"
-          :placeholder="t('configDevice.rfaHolder')"
-          class="reason-input"
-          type="textarea"
-          :rows="3"
-          @input="updateTempRelations"
-        />
+      <div class="card selection-area">
+        <div class="control-row">
+          <!-- 左侧人员选择 -->
+          <div class="control-group">
+            <label class="control-title">{{ t('devicePerson.rp') }}</label>
+            <div class="person-selector">
+              <el-select
+                v-model="selectedPersons"
+                multiple
+                filterable
+                :placeholder="t('configPerson.selectPersons')"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="person in simpleUsers"
+                  :key="person.id"
+                  :label="person.nickname"
+                  :value="person.id"
+                />
+              </el-select>
+            </div>
+          </div>
+
+          <div class="control-group">
+            <label class="control-title">{{ t('configDevice.reasonForAdjustment') }}</label>
+            <div class="reason-input-wrapper">
+              <el-input
+                v-model="formData.reason"
+                :placeholder="t('configDevice.rfaHolder')"
+                class="reason-input"
+                type="textarea"
+                :rows="4"
+                resize="none"
+                @input="updateTempRelations"
+              />
+            </div>
+          </div>
+        </div>
       </div>
+
       <el-button
         type="primary"
         size="large"
+        style="min-width: 180px;"
         @click="submitRelations"
-        :disabled="tempRelations.length === 0 || !formData.reason.trim()"
+        :disabled="tempRelations.length === 0 || !formData.reason.trim() || selectedPersons.length === 0"
       >
         {{ t('iotMaintain.save') }}
       </el-button>
+
       <div class="temp-list card" v-if="false">
         <h3>{{ t('configPerson.adjustmentRecords') }}</h3>
         <el-table :data="tempRelations" style="width: 100%">
@@ -105,10 +137,12 @@ import { ref, computed } from 'vue'
 import { ElMessage } from 'element-plus'
 import {defaultProps, handleTree} from "@/utils/tree";
 import * as DeptApi from "@/api/system/dept";
+import * as UserApi from "@/api/system/user";
 import {IotDeviceApi, IotDeviceVO} from "@/api/pms/device";
 import DeptTree2 from "@/views/pms/device/DeptTree2.vue";
 import { useRouter } from 'vue-router'
 import { useTagsViewStore } from "@/store/modules/tagsView";
+import {UserVO} from "@/api/system/user";
 
 const router = useRouter()
 const { t } = useI18n() // 国际化
@@ -140,6 +174,9 @@ const deptTreeRef = ref<InstanceType<typeof DeptTree2>>()
 
 const emit = defineEmits(['success', 'node-click']) // 定义 success 树点击 事件,用于操作成功后的回调
 
+const simpleUsers = ref<UserVO[]>([])     // 人员下拉列表选项
+const selectedPersons = ref<number[]>([]) // 存储选中的人员ID
+
 // 响应式数据
 const tempRelationsMap = ref(new Map<number, {
   deviceId: number
@@ -195,6 +232,16 @@ watch([selectedDevices, selectedDeptId], () => {
   updateTempRelations();
 }, {deep: true, immediate: true, debounce: 100})
 
+// 监听部门变化
+watch(selectedDeptId, (newVal) => {
+  if (newVal) {
+    loadDeptPersons(newVal as number)
+  } else {
+    simpleUsers.value = []
+  }
+  selectedPersons.value = [] // 切换部门时清空已选人员
+})
+
 // 修改部门变更处理方法
 const handleDeptChange = (deptId) => {
   if (!deptId) {
@@ -233,6 +280,26 @@ const getDeviceList = async () => {
   }
 }
 
+// 选择部门后 加载部门人员
+const loadDeptPersons = async (deptId: number) => {
+  if (!deptId) {
+    simpleUsers.value = []
+    return
+  }
+  try {
+    // 调用API获取部门人员
+    const params = { deptId: deptId, pageNo: 1, pageSize: 10 }
+    const data = await UserApi.simpleUserList(params)
+    simpleUsers.value = data.map(user => ({
+      id: user.id,
+      nickname: user.nickname || user.username
+    }))
+  } catch (error) {
+    console.error('获取部门人员失败:', error)
+    simpleUsers.value = []
+  }
+}
+
 // 计算选中的设备原部门集合
 const originDeptIds = computed(() =>
   selectedDevices.value
@@ -286,7 +353,8 @@ const submitRelations = async () => {
     const submitData = tempRelations.value.map(r => ({
       deviceId: r.deviceId,
       deptId: r.deptId,
-      reason: r.reason
+      reason: r.reason,
+      personIds: selectedPersons.value // 添加人员ID列表
     }))
     await IotDeviceApi.saveDeviceAllot(submitData)
     // 模拟API调用
@@ -359,7 +427,7 @@ onMounted(async () => {
 }
 
 .submit-area {
-  margin-top: 5px;
+  margin-top: 20px;
   text-align: center;
 }
 
@@ -428,4 +496,52 @@ h3 {
   text-align: center;
   color: #999;
 }
+
+.control-row {
+  display: flex;
+  width: 100%;
+  gap: 20px;
+}
+
+/* 调整文本域高度 */
+.reason-input-wrapper :deep(.el-textarea__inner) {
+  height: 100% !important;
+  min-height: 100px;
+}
+
+/* 响应式调整 */
+@media (max-width: 992px) {
+  .control-row {
+    flex-direction: column;
+    gap: 15px;
+  }
+
+  .control-group {
+    width: 100%;
+  }
+}
+
+.selection-area {
+  display: flex;
+}
+
+.control-group {
+  flex: 1;
+  min-width: 0;
+  display: flex;
+  flex-direction: column;
+}
+
+.control-title {
+  display: block;
+  margin-bottom: 8px;
+  font-weight: bold;
+  color: #606266;
+}
+
+.person-selector,
+.reason-input-wrapper {
+  flex: 1;
+  min-height: 100px;
+}
 </style>

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

@@ -9,7 +9,7 @@
       label-width="68px"
     >
       <el-form-item label="工厂" prop="factoryId">
-        <el-select v-model="queryParams.factoryId" clearable placeholder="请选择" class="!w-240px" @change="selectedFactoryChange">
+        <el-select v-model="queryParams.factoryId" clearable filterable placeholder="请选择" class="!w-240px" @change="selectedFactoryChange">
           <el-option
             v-for="item in factoryList"
             :key="item.id"
@@ -31,7 +31,7 @@
       </el-form-item>
       -->
       <el-form-item label="成本中心" prop="costCenterId">
-        <el-select v-model="queryParams.costCenterId" clearable placeholder="请选择" class="!w-240px">
+        <el-select v-model="queryParams.costCenterId" clearable filterable placeholder="请选择" class="!w-240px">
           <el-option
             v-for="item in costCenterList"
             :key="item.id"

+ 2 - 2
src/views/pms/iotsapstock/index.vue

@@ -9,7 +9,7 @@
       label-width="68px"
     >
       <el-form-item label="工厂" prop="factoryId">
-        <el-select v-model="queryParams.factoryId" clearable placeholder="请选择" class="!w-240px" @change="selectedFactoryChange">
+        <el-select v-model="queryParams.factoryId" clearable filterable placeholder="请选择" class="!w-240px" @change="selectedFactoryChange">
           <el-option
             v-for="item in factoryList"
             :key="item.id"
@@ -19,7 +19,7 @@
         </el-select>
       </el-form-item>
       <el-form-item label="库存地点" prop="storageLocationId">
-        <el-select v-model="queryParams.storageLocationId" clearable placeholder="请选择" class="!w-240px">
+        <el-select v-model="queryParams.storageLocationId" clearable filterable placeholder="请选择" class="!w-240px">
           <el-option
             v-for="item in storageLocationList"
             :key="item.id"

+ 2 - 2
src/views/pms/material/MaterialGroupTree.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="head-container">
-    <el-input v-model="materialGroupName" class="mb-20px" clearable placeholder="请输入物料组名称">
+    <el-input v-model="materialGroupName" class="mb-20px" clearable placeholder="请输入分类名称">
       <template #prefix>
         <Icon icon="ep:search" />
       </template>
@@ -79,7 +79,7 @@ const handleMenuClick = (action) => {
 const getTree = async () => {
   const res = await MaterialGroupApi.getSimpleMaterialGroupList()
   materialGroupList.value = []
-  let device: Tree = { id: 0, name: '顶级物料组分类', children: [] }
+  let device: Tree = { id: 0, name: '物料组分类', children: [] }
   device.children = handleTree(res)
   materialGroupList.value.push(device)
   // materialGroupList.value.push(...handleTree(res))

+ 3 - 3
src/views/system/dept/DeptForm.vue

@@ -43,7 +43,7 @@
       </el-form-item>
       -->
       <el-form-item label="SAP工厂">
-        <el-select v-model="formData.factoryIds" multiple placeholder="请选择" @change="selectedFactoryChange">
+        <el-select v-model="formData.factoryIds" multiple placeholder="请选择" @change="selectedFactoryChange" filterable clearable>
           <el-option
             v-for="item in factoryList"
             :key="item.id"
@@ -53,7 +53,7 @@
         </el-select>
       </el-form-item>
       <el-form-item label="SAP成本中心">
-        <el-select v-model="formData.costCenterIds" multiple placeholder="请选择">
+        <el-select v-model="formData.costCenterIds" multiple placeholder="请选择" filterable clearable>
           <el-option
             v-for="item in costCenterList"
             :key="item.id"
@@ -63,7 +63,7 @@
         </el-select>
       </el-form-item>
       <el-form-item label="SAP库存地点">
-        <el-select v-model="formData.stockLocationIds" multiple placeholder="请选择">
+        <el-select v-model="formData.stockLocationIds" multiple placeholder="请选择" filterable clearable>
           <el-option
             v-for="item in stockLocationList"
             :key="item.id"