index.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <template>
  2. <div class="page">
  3. <el-card shadow="nover">
  4. <el-form inline>
  5. <el-form-item label="名称">
  6. <el-input v-model="searchParams.keyWord" placeholder="请输入关键字" clearable @keyup.enter="handleSearch" />
  7. </el-form-item>
  8. <el-form-item label="类型">
  9. <el-select v-model="searchParams.types" placeholder="请选择类型" clearable @clear="() => searchParams.types = -1" @change="handleSearch">
  10. <el-option label="主链" :value="1" />
  11. <el-option label="子链" :value="2" />
  12. <el-option label="全部" :value="-1" />
  13. </el-select>
  14. </el-form-item>
  15. <el-form-item label="状态">
  16. <el-select v-model="searchParams.status" placeholder="请选择状态" clearable @clear="() => searchParams.status = -1" @change="handleSearch">
  17. <el-option label="已启动" :value="1" />
  18. <el-option label="已停止" :value="0" />
  19. <el-option label="全部" :value="-1" />
  20. </el-select>
  21. </el-form-item>
  22. <el-form-item>
  23. <el-button type="primary" @click="handleSearch">
  24. <el-icon><ele-Search /></el-icon>
  25. 搜索
  26. </el-button>
  27. <!-- <el-button @click="handleReset">
  28. <el-icon><ele-Refresh /></el-icon>
  29. 重置
  30. </el-button> -->
  31. </el-form-item>
  32. <el-form-item>
  33. <el-button type="primary" v-auth="'add'" @click="addOrEdit()">
  34. <el-icon>
  35. <ele-FolderAdd />
  36. </el-icon>
  37. 新增规则编排
  38. </el-button>
  39. </el-form-item>
  40. </el-form>
  41. <el-table :data="tableData" style="width: 100%" v-loading="loading">
  42. <el-table-column type="index" label="序号" width="80" align="center" />
  43. <el-table-column prop="types" label="类型" width="70" align="center">
  44. <template #default="scope">
  45. <el-tag type="primary" size="small" v-if="scope.row.types == 1">主链</el-tag>
  46. <el-tag type="success" size="small" v-else>子链</el-tag>
  47. </template>
  48. </el-table-column>
  49. <el-table-column prop="name" label="名称" show-overflow-tooltip></el-table-column>
  50. <el-table-column prop="expound" label="说明" show-overflow-tooltip></el-table-column>
  51. <el-table-column prop="createdAt" label="创建时间" min-width="100" align="center"></el-table-column>
  52. <el-table-column prop="status" label="状态" width="100" align="center">
  53. <template #default="scope">
  54. <el-tag type="success" size="small" v-if="scope.row.status == 1">已启动</el-tag>
  55. <el-tag type="info" size="small" v-else>已停止</el-tag>
  56. </template>
  57. </el-table-column>
  58. <el-table-column label="操作" width="200" align="center">
  59. <template #default="scope">
  60. <el-button size="small" text type="info" v-auth="'startOrStop'" v-if="scope.row.status" @click="setStatus(scope.row, 0)">停止</el-button>
  61. <el-button size="small" text type="primary" v-auth="'startOrStop'" v-else @click="setStatus(scope.row, 1)">启动</el-button>
  62. <el-button size="small" text type="primary" v-auth="'edit'" @click="addOrEdit(scope.row)">编辑</el-button>
  63. <el-button size="small" text type="warning" @click="edit(scope.row)">规则编辑</el-button>
  64. <el-button size="small" text type="info" v-auth="'del'" @click="onDel(scope.row)">删除</el-button>
  65. </template>
  66. </el-table-column>
  67. </el-table>
  68. <pagination v-if="params.total" :total="params.total" v-model:page="params.pageNum" v-model:limit="params.pageSize" @pagination="getList()" />
  69. <EditForm :model="model" ref="editFormRef" @getList="getList(1)"></EditForm>
  70. </el-card>
  71. </div>
  72. </template>
  73. <script lang="ts" setup>
  74. import { ref, reactive, watch } from "vue";
  75. import api from "/@/api/rule";
  76. import { ElMessageBox, ElMessage } from "element-plus";
  77. import { useSearch } from "/@/hooks/useCommon";
  78. import EditForm from "./edit.vue";
  79. import axios from "axios";
  80. import { getToken } from "/@/utils/auth";
  81. const editFormRef = ref();
  82. // 规则引擎模式 node-red、 sagoo-rule
  83. const model: "node-red" | "sagoo-rule" = import.meta.env.VITE_RULE_MODEL;
  84. const searchParams = reactive({
  85. keyWord: '',
  86. types: -1,
  87. status: -1
  88. });
  89. // 监听搜索参数变化,确保在API请求中正确传递搜索条件
  90. watch(searchParams, (newVal: any) => {
  91. // 处理搜索参数的值
  92. for (const key in newVal) {
  93. if (newVal[key] === '' || newVal[key] === null) {
  94. // 如果是类型或状态字段,在清除时设置为-1(全部)
  95. if (key === 'types' || key === 'status') {
  96. params[key] = -1;
  97. searchParams[key] = -1; // 同步更新searchParams
  98. } else {
  99. delete params[key];
  100. }
  101. } else {
  102. params[key] = newVal[key];
  103. }
  104. }
  105. }, { deep: true });
  106. const { params, tableData, getList, loading } = useSearch<any[]>(api.getList, "Data", searchParams);
  107. const headers = {
  108. Authorization: "Bearer " + getToken(),
  109. };
  110. const flowsUrl = window.location.origin + "/rule-engine/flows";
  111. getList();
  112. // 搜索
  113. const handleSearch = () => {
  114. getList(1);
  115. };
  116. // 重置功能已在模板中被注释掉
  117. // 如果需要重新启用重置功能,请取消注释并使用以下代码:
  118. /*
  119. const handleReset = () => {
  120. searchParams.keyWord = '';
  121. searchParams.types = -1;
  122. searchParams.status = -1;
  123. getList(1);
  124. };
  125. */
  126. const addOrEdit = async (row?: any) => {
  127. if (row) {
  128. editFormRef.value.open(row);
  129. return;
  130. } else {
  131. editFormRef.value.open();
  132. }
  133. };
  134. const setStatus = async (row: any, status: number) => {
  135. if (model === "sagoo-rule") {
  136. axios
  137. .get(`${import.meta.env.VITE_RULE_SERVER_URL}/api/v1/rule/${row.flowId}/${status ? "enable" : "stop"}`, { headers })
  138. .then(() => {
  139. api
  140. .setStatus(row.id, status)
  141. .then(() => {
  142. ElMessage.success("操作成功");
  143. getList();
  144. })
  145. .catch(() => {
  146. ElMessage.error("操作失败");
  147. });
  148. })
  149. .catch(() => {
  150. ElMessage.error("操作失败");
  151. });
  152. } else {
  153. // 找到所有规则
  154. const { data: flows } = await axios.get(flowsUrl, { headers });
  155. const flow = flows.find((item: any) => item.id === row.flowId);
  156. if (!flow) {
  157. ElMessage.error("规则不存在");
  158. return;
  159. }
  160. // 改变指定规则状态
  161. flow.disabled = status ? false : true;
  162. // 设置规则状态
  163. await axios.post(flowsUrl, flows, { headers });
  164. api
  165. .setStatus(row.id, status)
  166. .then(() => {
  167. ElMessage.success("操作成功");
  168. getList();
  169. })
  170. .catch(() => {
  171. ElMessage.error("操作失败");
  172. });
  173. }
  174. };
  175. const edit = async (row: any) => {
  176. if (model == "sagoo-rule") {
  177. localStorage.setItem("auth-tokens", `{"access_token":"${getToken()}"}`);
  178. const url = "/plugin/rule/index.html#" + row.flowId;
  179. window.open(url);
  180. } else if (model == "node-red") {
  181. localStorage.setItem("auth-tokens", `{"access_token":"${getToken()}"}`);
  182. const url = "/rule-engine/#flow/" + row.flowId;
  183. window.open(url);
  184. }
  185. };
  186. const onDel = (row: any) => {
  187. ElMessageBox.confirm(`此操作将删除:“${row.name}”,是否继续?`, "提示", {
  188. confirmButtonText: "确认",
  189. cancelButtonText: "取消",
  190. type: "warning",
  191. }).then(async () => {
  192. if (model == "sagoo-rule") {
  193. await axios.delete(import.meta.env.VITE_RULE_SERVER_URL + "/api/v1/rules/" + row.flowId, { headers }).catch(() => {
  194. ElMessage.error("规则不存在");
  195. });
  196. } else if (model == "node-red") {
  197. // 找到所有规则
  198. const { data: flows } = await axios.get(flowsUrl, { headers });
  199. const flowIndex = flows.findIndex((item: any) => item.id === row.flowId);
  200. if (flowIndex >= 0) {
  201. // 删除指定规则
  202. flows.splice(flowIndex, 1);
  203. // 删除当前规则下的各个节点信息
  204. const newFlows = flows.filter((item: any) => {
  205. if (item.z === row.flowId) {
  206. return false;
  207. } else {
  208. return true;
  209. }
  210. });
  211. // 设置规则状态
  212. await axios.post(flowsUrl, newFlows, { headers });
  213. }
  214. }
  215. await api.del([row.id as string]);
  216. ElMessage.success("删除成功");
  217. getList();
  218. });
  219. };
  220. </script>