From db42d47f5692ef64e5436c5a6d29dcb537b44596 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期一, 26 一月 2026 16:36:13 +0800
Subject: [PATCH] 浪潮对接单点登录:mis调整

---
 src/views/oaSystem/projectManagement/index.vue |  481 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 481 insertions(+), 0 deletions(-)

diff --git a/src/views/oaSystem/projectManagement/index.vue b/src/views/oaSystem/projectManagement/index.vue
new file mode 100644
index 0000000..2a0ec3a
--- /dev/null
+++ b/src/views/oaSystem/projectManagement/index.vue
@@ -0,0 +1,481 @@
+<template>
+  <div class="app-container">
+    <!-- 椤堕儴鎼滅储鍜屾搷浣滄爮 -->
+    <el-form :model="queryParams" ref="queryRef" :inline="true" label-width="80px">
+      <el-form-item label="椤圭洰鍚嶇О" prop="projectName">
+        <el-input
+          v-model="queryParams.projectName"
+          placeholder="璇疯緭鍏ラ」鐩悕绉�"
+          clearable
+          style="width: 240px"
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="璐熻矗浜�" prop="managerName">
+        <el-input
+          v-model="queryParams.managerName"
+          placeholder="璇疯緭鍏ヨ礋璐d汉濮撳悕"
+          clearable
+          style="width: 240px"
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="鐘舵��" prop="status">
+        <el-select
+          v-model="queryParams.status"
+          placeholder="椤圭洰鐘舵��"
+          clearable
+          style="width: 150px"
+        >
+          <el-option label="瑙勫垝涓�" value="planning" />
+          <el-option label="杩涜涓�" value="inProgress" />
+          <el-option label="宸插畬鎴�" value="completed" />
+          <el-option label="宸叉殏鍋�" value="paused" />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">鎼滅储</el-button>
+        <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 宸ュ叿鏍� -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['oaSystem:project:add']"
+        >鏂板椤圭洰</el-button>
+      </el-col>
+      <!-- <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['oaSystem:project:edit']"
+        >缂栬緫椤圭洰</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['oaSystem:project:remove']"
+        >鍒犻櫎椤圭洰</el-button>
+      </el-col> -->
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['oaSystem:project:export']"
+        >瀵煎嚭椤圭洰</el-button>
+      </el-col>
+    </el-row>
+
+    <!-- 椤圭洰鍒楄〃琛ㄦ牸 -->
+    <el-table
+      v-loading="loading"
+      :data="projectList"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="50" align="center" />
+      <el-table-column
+        label="椤圭洰缂栧彿"
+        align="center"
+        prop="projectId"
+        width="100"
+      />
+      <el-table-column
+        label="椤圭洰鍚嶇О"
+        align="center"
+        prop="projectName"
+        :show-overflow-tooltip="true"
+      />
+      <el-table-column
+        label="璐熻矗浜�"
+        align="center"
+        prop="managerName"
+      />
+      <el-table-column
+        label="寮�濮嬫棩鏈�"
+        align="center"
+        prop="startDate"
+        width="120"
+      />
+      <el-table-column
+        label="缁撴潫鏃ユ湡"
+        align="center"
+        prop="endDate"
+        width="120"
+      />
+      <el-table-column
+        label="鐘舵��"
+        align="center"
+        prop="status"
+        width="90"
+      >
+        <template #default="scope">
+          <el-tag :type="getStatusType(scope.row.status)">{{ getStatusText(scope.row.status) }}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="瀹屾垚搴�"
+        align="center"
+        prop="completionRate"
+        width="100"
+      >
+        <template #default="scope">
+          <el-progress :percentage="scope.row.completionRate" :stroke-width="6" />
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="鎿嶄綔"
+        align="center"
+        width="180"
+        class-name="small-padding fixed-width"
+      >
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            icon="Search"
+            @click="handleView(scope.row)"
+            v-hasPermi="['oaSystem:project:query']"
+          >璇︽儏</el-button>
+          <el-button
+            link
+            type="primary"
+            icon="Edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['oaSystem:project:edit']"
+          >缂栬緫</el-button>
+          <el-button
+            link
+            type="danger"
+            icon="Delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['oaSystem:project:remove']"
+          >鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 鍒嗛〉缁勪欢 -->
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 椤圭洰琛ㄥ崟瀵硅瘽妗� -->
+    <el-dialog :title="title" v-model="open" width="600px" append-to-body>
+      <project-form
+        ref="projectFormRef"
+        :form="form"
+        :rules="rules"
+        :visible="open"
+      />
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="cancel">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitForm">纭畾</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, computed, onMounted } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import Pagination from '@/components/Pagination';
+import ProjectForm from './components/projectForm.vue';
+import { useRouter } from 'vue-router';
+const { proxy } = getCurrentInstance();
+// 瀵煎叆椤圭洰绠$悊API鎺ュ彛
+import { listProject, addProject, updateProject, delProject, exportProject } from '@/api/oaSystem/projectManagement';
+// import { listUser } from '@/api/system/user'; // 瀵煎叆鐢ㄦ埛鍒楄〃API鎺ュ彛
+
+// 鍒涘缓router瀹炰緥
+const router = useRouter();
+
+// 琛ㄦ牸鏁版嵁
+const projectList = ref([]);
+const loading = ref(true);
+const total = ref(0);
+const queryParams = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  projectName: '',
+  managerName: '',
+  status: ''
+});
+
+// 琛ㄥ崟鏁版嵁
+const form = reactive({
+  projectId: undefined,
+  projectName: '',
+  description: '',
+  startDate: '',
+  endDate: '',
+  managerId: '',
+  managerName: '',
+  status: 'planning',
+  completionRate: 0
+});
+
+// 琛ㄥ崟鏍¢獙瑙勫垯
+const rules = {
+  projectName: [
+    { required: true, message: '椤圭洰鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' },
+    { min: 2, max: 50, message: '椤圭洰鍚嶇О闀垮害鍦� 2 鍒� 50 涓瓧绗�', trigger: 'blur' }
+  ],
+  startDate: [
+    { required: true, message: '寮�濮嬫棩鏈熶笉鑳戒负绌�', trigger: 'change' }
+  ],
+  endDate: [
+    { required: true, message: '缁撴潫鏃ユ湡涓嶈兘涓虹┖', trigger: 'change' }
+  ],
+  managerId: [
+    { required: true, message: '璐熻矗浜轰笉鑳戒负绌�', trigger: 'blur' }
+  ]
+};
+
+// 瀵硅瘽妗嗙姸鎬�
+const open = ref(false);
+const title = ref('');
+const projectFormRef = ref();
+const queryRef = ref();
+
+// 閫変腑鐘舵��
+const multiple = computed(() => {
+  return selectedRowKeys.value.length === 0;
+});
+const single = computed(() => {
+  return selectedRowKeys.value.length !== 1;
+});
+const selectedRowKeys = ref([]);
+
+// 鑾峰彇椤圭洰鍒楄〃
+const getList = async () => {
+  loading.value = true;
+    try {
+    const { data } = await listProject(queryParams);
+    projectList.value = data.records;
+    total.value = data.total;
+  } catch (error) {
+    ElMessage.error('鑾峰彇椤圭洰鍒楄〃澶辫触');
+    console.error('鑾峰彇椤圭洰鍒楄〃澶辫触:', error);
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 鎼滅储
+const handleQuery = () => {
+  queryParams.pageNum = 1;
+  getList();
+};
+
+// 閲嶇疆
+const resetQuery = () => {
+  if (queryRef.value) {
+    queryRef.value.resetFields();
+  }
+  handleQuery();
+};
+
+// 閫変腑琛屽彉鍖�
+const handleSelectionChange = (selection) => {
+  selectedRowKeys.value = selection.map(item => item.projectId);
+};
+
+// 鏂板椤圭洰 
+const handleAdd = () => {
+  resetForm();
+  open.value = true;
+  title.value = '鏂板椤圭洰';
+};
+
+// 缂栬緫椤圭洰 
+const handleUpdate = async (row) => {
+  resetForm();
+  const projectId = row.projectId || selectedRowKeys.value[0];
+    try {
+    // const { data } = await getProject(projectId);
+    Object.assign(form, row);
+    open.value = true;
+    title.value = '缂栬緫椤圭洰';
+  } catch (error) {
+    ElMessage.error('鑾峰彇椤圭洰璇︽儏澶辫触');
+    console.error('鑾峰彇椤圭洰璇︽儏澶辫触:', error);
+  }
+};
+
+// 鍒犻櫎椤圭洰
+const handleDelete = async (row) => {
+  // const projectIds = row.projectId ? [row.projectId] : selectedRowKeys.value;
+  const projectNames = row.projectName ? [row.projectName] : 
+    projectList.value.filter(item => projectIds.includes(item.projectId)).map(item => item.projectName);
+  
+  const confirmMessage = `纭畾瑕佸垹闄ら」鐩� "${projectNames.join('銆�')}" 鍚楋紵`;
+  await ElMessageBox.confirm(confirmMessage, '纭鎿嶄綔', {
+    confirmButtonText: '纭畾',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  }).catch(() => {
+    throw new Error('鍙栨秷鍒犻櫎');
+  });
+  
+  try {
+    // if (projectIds.length === 1) {
+      await delProject(row.projectId);
+    // } else {
+    //   await delProjectBatch(projectIds);
+    // }
+    ElMessage.success('鍒犻櫎鎴愬姛');
+    getList();
+  } catch (error) {
+    if (error.message !== '鍙栨秷鍒犻櫎') {
+      ElMessage.error('鍒犻櫎澶辫触');
+      console.error('鍒犻櫎椤圭洰澶辫触:', error);
+    }
+  }
+  // try {
+  //   await ElMessageBox.confirm(confirmMessage, '纭鎿嶄綔', {
+  //     confirmButtonText: '纭畾',
+  //     cancelButtonText: '鍙栨秷',
+  //     type: 'warning'
+  //   });
+    
+  //   // 妯℃嫙缃戠粶寤惰繜
+  //   await new Promise(resolve => setTimeout(resolve, 300));
+   
+    
+  //   ElMessage.success('鍒犻櫎鎴愬姛');
+  //   getList();
+  // } catch (error) {
+  //   if (error !== 'cancel') {
+  //     console.error('鍒犻櫎椤圭洰澶辫触:', error);
+  //   }
+  // }
+};
+
+// 鏌ョ湅椤圭洰璇︽儏
+const handleView = (row) => {
+  const projectId = row.projectId;
+  // 璺宠浆鍒伴」鐩鎯呴〉闈�
+  router.push({
+    path: `/oaSystem/projectManagement/projectDetail/${projectId}`,
+    query: { projectName: row.projectName }
+  });
+};
+
+// 瀵煎嚭椤圭洰
+const handleExport = async () => {
+    let ids = [];
+    if (selectedRowKeys.value.length > 0) {
+      ids = selectedRowKeys.value; // 瀵煎嚭閫変腑鐨勯」鐩�
+    } else {
+      ids = projectList.value.map(item => item.projectId); // 瀵煎嚭鎵�鏈夐」鐩�
+    }
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+    .then(() => {
+      proxy.download(`/oA/project/export/${ids.join(',')}`, {}, "椤圭洰鏁版嵁.xlsx");
+      ElMessage.success("瀵煎嚭鎴愬姛");
+      ids = [];
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+// 鎻愪氦琛ㄥ崟
+const submitForm = async () => {
+  try {
+    await projectFormRef.value.validate();
+
+    if (form.projectId) {
+      await updateProject(form);
+      ElMessage.success('淇敼椤圭洰鎴愬姛');
+    } else {
+      console.log("form",form);
+      await addProject(form);
+      ElMessage.success('鏂板椤圭洰鎴愬姛');
+    }
+    open.value = false;
+    getList();
+  } catch (error) {
+    console.error('鎻愪氦琛ㄥ崟澶辫触:', error);
+  }
+};
+
+// 鍙栨秷
+const cancel = () => {
+  open.value = false;
+  resetForm();
+};
+
+// 閲嶇疆琛ㄥ崟
+const resetForm = () => {
+  form.projectId = undefined;
+  form.projectName = '';
+  form.description = '';
+  form.startDate = '';
+  form.endDate = '';
+  form.managerId = '';
+  form.managerName = '';
+  form.status = 'planning';
+  form.completionRate = 0;
+  if (projectFormRef.value) {
+    projectFormRef.value.resetFields();
+  }
+};
+
+// 鑾峰彇鐘舵�佹爣绛剧被鍨�
+const getStatusType = (status) => {
+  const statusTypeMap = {
+    planning: 'info',
+    inProgress: 'primary',
+    completed: 'success',
+    paused: 'warning'
+  };
+  return statusTypeMap[status] || 'default';
+};
+
+// 鑾峰彇鐘舵�佹枃鏈�
+const getStatusText = (status) => {
+  const statusTextMap = {
+    planning: '瑙勫垝涓�',
+    inProgress: '杩涜涓�',
+    completed: '宸插畬鎴�',
+    paused: '宸叉殏鍋�'
+  };
+  return statusTextMap[status] || status;
+};
+
+// 鍒濆鍖�
+onMounted(() => {
+  getList();
+});
+</script>
+
+<style scoped>
+.app-container {
+  padding: 20px;
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3