Ver Fonte

pms 日报 项目 责任人

zhangcl há 1 mês atrás
pai
commit
0c849b2cfb

+ 5 - 0
src/api/system/user/index.ts

@@ -28,6 +28,11 @@ export const simpleUserList = (params: PageParam) => {
   return request.get({ url: '/system/user/simpleUserList', params })
 }
 
+// 获取公司层级的部门包含的子部门下的所有人员
+export const companyDeptsEmployee = (params: PageParam) => {
+  return request.get({ url: '/system/user/companyDeptsEmployee', params })
+}
+
 // 查询用户详情
 export const getUser = (id: number) => {
   return request.get({ url: '/system/user/get?id=' + id })

+ 216 - 4
src/views/pms/iotprojectinfo/IotProjectInfoForm.vue

@@ -88,22 +88,79 @@
               check-strictly
               node-key="id"
               filterable
-              placeholder="请选择所在部门"
+              placeholder="请选择所属公司"
             />
           </el-form-item>
         </el-col>
         <el-col :span="12">
+          <el-form-item label="责任人" prop="responsiblePerson">
+            <span v-if="selectedUserNames" class="user-names">
+              {{ selectedUserNames }}
+            </span>
+            <el-button
+              type="primary"
+              size="small"
+              @click="openUserDialog"
+              style="margin-left: 10px;"
+              :disabled="!formData.deptId"
+            >
+              选择责任人
+            </el-button>
+            <div v-if="!formData.deptId" class="el-form-item__error">请先选择所属公司</div>
+          </el-form-item>
+        </el-col>
+
+      </el-row>
+      <el-row>
+        <el-col :span="24">
           <el-form-item label="备注" prop="remark">
             <el-input v-model="formData.remark" placeholder="请输入备注" type="textarea" />
           </el-form-item>
         </el-col>
       </el-row>
-
     </el-form>
   </ContentWrap>
 
   <CustomerList ref="customerZzFormRef" @choose="customerZzChoose" />
 
+  <!-- 责任人选择对话框 -->
+  <el-dialog
+    v-model="userDialogVisible"
+    title="选择责任人"
+    width="800px"
+    :before-close="handleUserDialogClose"
+    class="user-select-dialog"
+  >
+    <div class="transfer-container">
+      <el-transfer
+        v-model="selectedUserIds"
+        :data="userList"
+        :titles="['可选人员', '已选人员']"
+        :props="{ key: 'id', label: 'nickname' }"
+        filterable
+        class="transfer-component"
+      >
+        <template #default="{ option }">
+          <el-tooltip
+            effect="dark"
+            placement="top"
+            :content="`${option.nickname} - ${option.deptName || '未分配部门'}`"
+          >
+            <span class="transfer-option-text">
+              {{ option.nickname }} - {{ option.deptName || '未分配部门' }}
+            </span>
+          </el-tooltip>
+        </template>
+      </el-transfer>
+    </div>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button @click="handleUserDialogClose">取消</el-button>
+        <el-button type="primary" @click="confirmUserSelection">确定</el-button>
+      </span>
+    </template>
+  </el-dialog>
+
   <ContentWrap>
     <el-form style="float: right">
       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
@@ -112,20 +169,26 @@
   </ContentWrap>
 </template>
 <script setup lang="ts">
+
 import { IotProjectInfoApi, IotProjectInfoVO } from '@/api/pms/iotprojectinfo'
 import {defaultProps,handleTree} from "@/utils/tree";
 import * as DeptApi from "@/api/system/dept";
 import IotProjectTaskForm from '@/views/pms/iotprojectinfo/IotProjectTaskForm.vue'
 import CustomerList from '@/views/pms/device/CustomerList.vue'
 import {ref} from "vue";
+
 /** 项目信息 表单 */
 defineOptions({ name: 'IotProjectInfo' })
-const { params, name } = useRoute() // 查询参数
+
 import {useUserStore} from "@/store/modules/user";
 import {IotProjectTaskApi, IotProjectTaskVO} from "@/api/pms/iotprojecttask";
 import {ElMessageBox} from "element-plus";
 import {updateConfig} from "@/api/infra/config";
 import {useTagsViewStore} from "@/store/modules/tagsView";
+import * as UserApi from "@/api/system/user";
+import {UserVO} from "@/api/system/user";
+
+const { params, name } = useRoute() // 查询参数
 const id = params.id
 const { delView } = useTagsViewStore() // 视图操作
 const { currentRoute, push } = useRouter()
@@ -138,6 +201,15 @@ const formLoading = ref(false) // 表单的加载中:1)修改时的数据加
 const taskList = ref<IotProjectTaskVO[]>([]) // 列表的数据
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
 const loading = ref(true) // 列表的加载中
+const simpleUsers = ref<UserVO[]>([])     // 责任人列表
+
+// 添加责任人相关变量
+const userDialogVisible = ref(false);
+const userList = ref([]); // 所有用户列表
+const selectedUserIds = ref([]); // 选中的用户ID
+const selectedUserNames = ref(''); // 选中的用户名称显示
+const selectedUserList = ref([]); // 存储选中的用户对象列表
+
 const formData = ref({
   id: undefined,
   deptId: undefined,
@@ -151,6 +223,7 @@ const formData = ref({
   location: undefined,
   technique: undefined,
   payment: undefined,
+
   userName: useUserStore().getUser.name,
   userId: useUserStore().getUser.userId,
 })
@@ -189,6 +262,41 @@ const customerZzFormRef = ref()
 const openCustomerZz = () => {
   customerZzFormRef.value.open()
 }
+
+// 格式化用户名称显示
+const formatUserNames = (users) => {
+  if (!users || users.length === 0) return '';
+
+  const names = users.map(user => user.nickname);
+
+  if (names.length <= 2) {
+    return names.join(', ');
+  } else {
+    return `${names[0]}, ${names[1]}...`;
+  }
+};
+
+// 根据用户ID获取用户信息
+const fetchUserInfoByIds = async (userIds) => {
+  if (!userIds || userIds.length === 0) {
+    selectedUserList.value = [];
+    selectedUserNames.value = '';
+    return;
+  }
+
+  try {
+    const params = {
+      userIds: userIds
+    };
+    const response = await UserApi.companyDeptsEmployee(params); // 假设有这个API
+    selectedUserList.value = response;
+    selectedUserNames.value = formatUserNames(response);
+  } catch (error) {
+    console.error('获取用户信息失败:', error);
+    ElMessage.error('获取用户信息失败');
+  }
+};
+
 // 根据部门ID获取部门名称
 const getDeptNames = (deptIds) => {
   if (!deptIds || deptIds.length === 0) return '';
@@ -216,6 +324,65 @@ const isDeptDisabled = computed(() => {
   return formType.value === 'update' || deptList.value.length === 1;
 });
 
+// 打开用户选择对话框
+const openUserDialog = async () => {
+  try {
+    // 获取用户列表,传递部门ID参数
+    const params = {
+      deptIds: [formData.value.deptId] // 将部门ID转换为数组格式
+    };
+    // 获取用户列表
+    const response = await UserApi.companyDeptsEmployee(params);
+    userList.value = response;
+
+    // 设置当前已选中的用户
+    selectedUserIds.value = formData.value.responsiblePerson || [];
+
+    userDialogVisible.value = true;
+
+  } catch (error) {
+    console.error('获取用户列表失败:', error);
+    ElMessage.error('获取用户列表失败');
+  }
+};
+
+// 确认用户选择
+const confirmUserSelection = () => {
+  // 更新表单数据
+  formData.value.responsiblePerson = [...selectedUserIds.value];
+
+  // 更新显示的用户名称
+  updateSelectedUserNames();
+
+  userDialogVisible.value = false;
+};
+
+// 更新显示的用户名称
+const updateSelectedUserNames = () => {
+  console.log('已经保存的责任人:' + formData.value.responsiblePerson)
+  if (!formData.value.responsiblePerson || formData.value.responsiblePerson.length === 0) {
+    selectedUserNames.value = '';
+    return;
+  }
+
+  const selectedUsers = userList.value.filter(user =>
+    formData.value.responsiblePerson.includes(user.id)
+  );
+
+  const names = selectedUsers.map(user => user.nickname);
+
+  if (names.length <= 2) {
+    selectedUserNames.value = names.join(', ');
+  } else {
+    selectedUserNames.value = `${names[0]}, ${names[1]}...`;
+  }
+};
+
+// 关闭用户选择对话框
+const handleUserDialogClose = () => {
+  userDialogVisible.value = false;
+};
+
 const tableData = ref([
   {
     id: 1,
@@ -243,6 +410,16 @@ const open = async () => {
     try {
       formData.value = await IotProjectInfoApi.getIotProjectInfo(id)
 
+      // 如果已有责任人数据,获取用户信息并显示
+      if (formData.value.responsiblePerson && formData.value.responsiblePerson.length > 0) {
+        await fetchUserInfoByIds(formData.value.responsiblePerson);
+        selectedUserIds.value = [...formData.value.responsiblePerson];
+      }
+
+      // 如果已有责任人数据,更新显示
+      if (formData.value.responsiblePerson) {
+        // updateSelectedUserNames();
+      }
     } finally {
       formLoading.value = false
     }
@@ -254,6 +431,7 @@ const open = async () => {
     }
   }
 }
+
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
 /** 提交表单 */
@@ -303,7 +481,9 @@ const resetForm = () => {
     payment: undefined,
     userName: undefined,
     userId: undefined,
+    responsiblePerson: [], // 重置责任人字段
   }
+  selectedUserNames.value = '';
   formRef.value?.resetFields()
 }
 onMounted(async () => {
@@ -315,7 +495,6 @@ onMounted(async () => {
   if (deptList.value.length === 1) {
     formData.value.deptId = deptList.value[0].id;
   }
-
   open();
 })
 
@@ -489,3 +668,36 @@ const deleteRow = (index) => {
 };
 
 </script>
+
+<style scoped>
+.user-names {
+  padding: 5px 10px;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  background-color: #f5f7fa;
+  display: inline-block;
+  min-width: 200px;
+}
+
+.transfer-container {
+  text-align: center;
+  padding: 20px 0;
+}
+
+.transfer-component {
+  width: 100%;
+}
+
+:deep(.el-transfer-panel__item) {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  max-width: 100%;
+  padding: 6px 6px;
+}
+
+.transfer-option-text {
+  display: inline-block;
+  max-width: 100%;
+}
+</style>