From eb518a148441c7169ee562cef4b4c29d98d04067 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期五, 15 八月 2025 10:05:11 +0800
Subject: [PATCH] 完成RPA流程自动化

---
 src/api/collaborativeApproval/rpaManagement.js          |   77 +++++++++
 src/views/collaborativeApproval/rpaManagement/index.vue |  400 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 477 insertions(+), 0 deletions(-)

diff --git a/src/api/collaborativeApproval/rpaManagement.js b/src/api/collaborativeApproval/rpaManagement.js
new file mode 100644
index 0000000..6fc3368
--- /dev/null
+++ b/src/api/collaborativeApproval/rpaManagement.js
@@ -0,0 +1,77 @@
+import request from "@/utils/request";
+
+// 鏌ヨRPA鍒楄〃
+export function listRpa(query) {
+  return request({
+    url: "/collaborativeApproval/rpa/list",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏌ヨRPA璇︾粏
+export function getRpa(rpaId) {
+  return request({
+    url: "/collaborativeApproval/rpa/" + rpaId,
+    method: "get",
+  });
+}
+
+// 鏂板RPA
+export function addRpa(data) {
+  return request({
+    url: "/collaborativeApproval/rpa",
+    method: "post",
+    data: data,
+  });
+}
+
+// 淇敼RPA
+export function updateRpa(data) {
+  return request({
+    url: "/collaborativeApproval/rpa",
+    method: "put",
+    data: data,
+  });
+}
+
+// 鍒犻櫎RPA
+export function delRpa(rpaId) {
+  return request({
+    url: "/collaborativeApproval/rpa/" + rpaId,
+    method: "delete",
+  });
+}
+
+// 鎵归噺鍒犻櫎RPA
+export function delRpaBatch(rpaIds) {
+  return request({
+    url: "/collaborativeApproval/rpa/batch",
+    method: "delete",
+    data: rpaIds,
+  });
+}
+
+// 鍚姩RPA
+export function startRpa(rpaId) {
+  return request({
+    url: "/collaborativeApproval/rpa/start/" + rpaId,
+    method: "post",
+  });
+}
+
+// 鍋滄RPA
+export function stopRpa(rpaId) {
+  return request({
+    url: "/collaborativeApproval/rpa/stop/" + rpaId,
+    method: "post",
+  });
+}
+
+// 鑾峰彇RPA鐘舵��
+export function getRpaStatus(rpaId) {
+  return request({
+    url: "/collaborativeApproval/rpa/status/" + rpaId,
+    method: "get",
+  });
+}
diff --git a/src/views/collaborativeApproval/rpaManagement/index.vue b/src/views/collaborativeApproval/rpaManagement/index.vue
new file mode 100644
index 0000000..51cef73
--- /dev/null
+++ b/src/views/collaborativeApproval/rpaManagement/index.vue
@@ -0,0 +1,400 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <div>
+        <span class="search_title">绋嬪簭鍚嶏細</span>
+        <el-input
+          v-model="searchForm.programName"
+          style="width: 240px"
+          placeholder="璇疯緭鍏ョ▼搴忓悕鎼滅储"
+          @change="handleQuery"
+          clearable
+          :prefix-icon="Search"
+        />
+        <span class="search_title ml10">鎵ц鐘舵�侊細</span>
+        <el-select v-model="searchForm.status" clearable @change="handleQuery" style="width: 240px">
+          <el-option label="杩愯涓�" :value="'running'" />
+          <el-option label="宸插仠姝�" :value="'stopped'" />
+          <el-option label="寮傚父" :value="'error'" />
+        </el-select>
+        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
+          鎼滅储
+        </el-button>
+      </div>
+      <div>
+        <el-button type="primary" @click="openForm('add')">鏂板</el-button>
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+    </div>
+    <div class="table_list">
+      <PIMTable
+        rowKey="id"
+        :column="tableColumn"
+        :tableData="tableData"
+        :page="page"
+        :isSelection="true"
+        @selection-change="handleSelectionChange"
+        :tableLoading="tableLoading"
+        @pagination="pagination"
+        :total="page.total"
+      ></PIMTable>
+    </div>
+
+    <!-- RPA琛ㄥ崟寮圭獥 -->
+    <el-dialog
+      v-model="dialogVisible"
+      :title="dialogTitle"
+      width="500px"
+      :close-on-click-modal="false"
+    >
+      <el-form
+        ref="formRef"
+        :model="form"
+        :rules="rules"
+        label-width="100px"
+      >
+        <el-form-item label="绋嬪簭鍚�" prop="programName">
+          <el-input
+            v-model="form.programName"
+            placeholder="璇疯緭鍏ョ▼搴忓悕"
+            clearable
+          />
+        </el-form-item>
+        <el-form-item label="鎵ц鐘舵��" prop="status">
+          <el-select v-model="form.status" placeholder="璇烽�夋嫨鎵ц鐘舵��" style="width: 100%">
+            <el-option label="杩愯涓�" value="running" />
+            <el-option label="宸插仠姝�" value="stopped" />
+            <el-option label="寮傚父" value="error" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鎻忚堪" prop="description">
+          <el-input
+            v-model="form.description"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏PA绋嬪簭鎻忚堪"
+            clearable
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitForm">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { Search } from "@element-plus/icons-vue";
+import { onMounted, ref, reactive, toRefs } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import PIMTable from "@/components/PIMTable/PIMTable.vue";
+
+// 鍝嶅簲寮忔暟鎹�
+const data = reactive({
+  searchForm: {
+    programName: "",
+    status: "",
+  },
+  form: {
+    id: "",
+    programName: "",
+    status: "stopped",
+    description: "",
+    createTime: "",
+  },
+  dialogVisible: false,
+  dialogTitle: "",
+  dialogType: "add",
+  selectedIds: [],
+  tableLoading: false,
+  page: {
+    current: 1,
+    size: 100,
+    total: 0,
+  },
+  tableData: [],
+});
+
+const { searchForm, form, dialogVisible, dialogTitle, dialogType, selectedIds, tableLoading, page, tableData } = toRefs(data);
+
+// 琛ㄥ崟寮曠敤
+const formRef = ref();
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const rules = {
+  programName: [
+    { required: true, message: "璇疯緭鍏ョ▼搴忓悕", trigger: "blur" }
+  ],
+  status: [
+    { required: true, message: "璇烽�夋嫨鎵ц鐘舵��", trigger: "change" }
+  ]
+};
+
+// 琛ㄦ牸鍒楅厤缃�
+const tableColumn = ref([
+  {
+    label: "绋嬪簭鍚�",
+    prop: "programName",
+    // width: 200,
+  },
+  {
+    label: "鎵ц鐘舵��",
+    prop: "status",
+    dataType: "tag",
+    // width: 120,
+    formatData: (params) => {
+      const statusMap = {
+        running: "杩愯涓�",
+        stopped: "宸插仠姝�",
+        error: "寮傚父"
+      };
+      return statusMap[params] || params;
+    },
+    formatType: (params) => {
+      const typeMap = {
+        running: "success",
+        stopped: "info",
+        error: "danger"
+      };
+      return typeMap[params] || "info";
+    }
+  },
+  {
+    label: "鎻忚堪",
+    prop: "description",
+    // width: 300,
+    showOverflowTooltip: true,
+  },
+  {
+    label: "鍒涘缓鏃堕棿",
+    prop: "createTime",
+    // width: 180,
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: "right",
+    width: 230,
+    operation: [
+      {
+        name: "缂栬緫",
+        type: "text",
+        clickFun: (row) => {
+          openForm("edit", row);
+        }
+      },
+      {
+        name: "寮�濮�",
+        type: "text",
+        clickFun: (row) => {
+          handleStart(row);
+        },
+        disabled: (row) => row.status !== 'stopped'
+      },
+      {
+        name: "鍋滄",
+        type: "text",
+        clickFun: (row) => {
+          handleStop(row);
+        },
+        disabled: (row) => row.status === 'stopped'
+      }
+    ]
+  }
+]);
+
+// 妯℃嫙鏁版嵁
+const mockData = [
+  {
+    id: "1",
+    programName: "璁㈠崟澶勭悊RPA",
+    status: "running",
+    description: "鑷姩澶勭悊瀹㈡埛璁㈠崟锛屽寘鎷獙璇併�佸垎閰嶅拰纭",
+    createTime: "2024-01-15 10:30:00"
+  },
+  {
+    id: "2",
+    programName: "搴撳瓨鍚屾RPA",
+    status: "stopped",
+    description: "鍚屾澶氫釜浠撳簱鐨勫簱瀛樻暟鎹紝纭繚鏁版嵁涓�鑷存��",
+    createTime: "2024-01-14 15:20:00"
+  },
+  {
+    id: "3",
+    programName: "鎶ヨ〃鐢熸垚RPA",
+    status: "error",
+    description: "鑷姩鐢熸垚姣忔棩閿�鍞姤琛ㄥ拰搴撳瓨鎶ヨ〃",
+    createTime: "2024-01-13 09:15:00"
+  }
+];
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+  getList();
+});
+
+// 鏌ヨ鏁版嵁
+const handleQuery = () => {
+  page.value.current = 1;
+  getList();
+};
+
+const getList = () => {
+  tableLoading.value = true;
+  
+  // 妯℃嫙API璋冪敤寤惰繜
+  setTimeout(() => {
+    let filteredData = [...mockData];
+    
+    // 鏍规嵁鎼滅储鏉′欢杩囨护鏁版嵁
+    if (searchForm.value.programName) {
+      filteredData = filteredData.filter(item => 
+        item.programName.toLowerCase().includes(searchForm.value.programName.toLowerCase())
+      );
+    }
+    
+    if (searchForm.value.status) {
+      filteredData = filteredData.filter(item => item.status === searchForm.value.status);
+    }
+    
+    tableData.value = filteredData;
+    page.value.total = filteredData.length;
+    tableLoading.value = false;
+  }, 500);
+};
+
+// 鍒嗛〉澶勭悊
+const pagination = (obj) => {
+  page.value.current = obj.page;
+  page.value.size = obj.limit;
+  handleQuery();
+};
+
+// 閫夋嫨鍙樺寲澶勭悊
+const handleSelectionChange = (selection) => {
+  selectedIds.value = selection.map(item => item.id);
+};
+
+// 鎵撳紑琛ㄥ崟
+const openForm = (type, row) => {
+  dialogType.value = type;
+  dialogVisible.value = true;
+  
+  if (type === "add") {
+    dialogTitle.value = "娣诲姞RPA";
+    form.value = {
+      id: "",
+      programName: "",
+      status: "stopped",
+      description: "",
+      createTime: "",
+    };
+  } else {
+    dialogTitle.value = "缂栬緫RPA";
+    form.value = { ...row };
+  }
+};
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = async () => {
+  if (!formRef.value) return;
+  
+  try {
+    await formRef.value.validate();
+    
+    if (dialogType.value === "add") {
+      // 娣诲姞鏂癛PA
+      const newRPA = {
+        id: Date.now().toString(),
+        programName: form.value.programName,
+        status: form.value.status,
+        description: form.value.description,
+        createTime: new Date().toLocaleString(),
+      };
+      
+      mockData.unshift(newRPA);
+      ElMessage.success("RPA娣诲姞鎴愬姛");
+    } else {
+      // 缂栬緫RPA
+      const index = mockData.findIndex(item => item.id === form.value.id);
+      if (index !== -1) {
+        mockData[index] = { ...form.value };
+        ElMessage.success("RPA鏇存柊鎴愬姛");
+      }
+    }
+    
+    dialogVisible.value = false;
+    getList();
+  } catch (error) {
+    console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+  }
+};
+
+// 寮�濮婻PA
+const handleStart = (row) => {
+  ElMessageBox.confirm(`纭畾瑕佸惎鍔≧PA绋嬪簭"${row.programName}"鍚楋紵`, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    row.status = "running";
+    ElMessage.success("RPA鍚姩鎴愬姛");
+    getList();
+  }).catch(() => {
+    // 鐢ㄦ埛鍙栨秷
+  });
+};
+
+// 鍋滄RPA
+const handleStop = (row) => {
+  ElMessageBox.confirm(`纭畾瑕佸仠姝PA绋嬪簭"${row.programName}"鍚楋紵`, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    row.status = "stopped";
+    ElMessage.success("RPA鍋滄鎴愬姛");
+    getList();
+  }).catch(() => {
+    // 鐢ㄦ埛鍙栨秷
+  });
+};
+
+// 鍒犻櫎RPA
+const handleDelete = () => {
+  let ids = [];
+  if (selectedIds.value.length > 0) {
+    ids = selectedIds.value.map((item) => item.id);
+  } else {
+    ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑RPA");
+    return;
+  }
+  
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    // 浠庢ā鎷熸暟鎹腑鍒犻櫎閫変腑鐨勯」
+    ids.forEach(id => {
+      const index = mockData.findIndex(item => item.id === id);
+      if (index !== -1) {
+        mockData.splice(index, 1);
+      }
+    });
+    
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    selectedIds.value = [];
+    getList();
+  }).catch(() => {
+    // 鐢ㄦ埛鍙栨秷
+  });
+};
+</script>
+
+<style scoped></style>

--
Gitblit v1.9.3