From 4ce045c9de6c3b321a510aa478ae430cc1366c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=B9=8F?= Date: Wed, 8 Jul 2026 12:02:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E8=A7=84=E5=88=99=E7=AE=A1=E7=90=86):=20?= =?UTF-8?q?=E8=A7=84=E5=88=99=E5=88=86=E7=B1=BB=E6=8E=92=E5=BA=8F=EF=BC=8C?= =?UTF-8?q?=E8=A7=84=E5=88=99=E5=88=97=E8=A1=A8=E9=A1=B5=E9=9D=A2=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E8=A7=84=E5=88=99=E5=A4=8D=E5=88=B6=E5=BC=B9=E7=AA=97?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/module_rule/rule.ts | 4 +- src/views/module_rule/rule_category/index.vue | 15 +--- src/views/module_rule/rule_list/index.vue | 81 ++++++++++++++++++- 3 files changed, 83 insertions(+), 17 deletions(-) diff --git a/src/api/module_rule/rule.ts b/src/api/module_rule/rule.ts index b9483a0..2967871 100644 --- a/src/api/module_rule/rule.ts +++ b/src/api/module_rule/rule.ts @@ -120,11 +120,11 @@ const RuleAPI = { }); }, - /** 批量修改状态(预留) */ + /** 批量修改状态(PUT /rule/status/batch) */ batchStatus(ids: number[], status: RuleStatus) { return request({ url: `${RULE_PATH}/status/batch`, - method: "patch", + method: "put", data: { ids, status }, }); }, diff --git a/src/views/module_rule/rule_category/index.vue b/src/views/module_rule/rule_category/index.vue index 6910202..7dd07e1 100644 --- a/src/views/module_rule/rule_category/index.vue +++ b/src/views/module_rule/rule_category/index.vue @@ -125,6 +125,7 @@ defineOptions({ name: "RuleCategory" }); import { ref, reactive, computed, onMounted } from "vue"; +import { useRuleCategory } from "@/views/module_rule/useRuleCategory"; import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from "element-plus"; import { Plus, Edit, Delete, ArrowRight } from "@element-plus/icons-vue"; import { RuleCategoryAPI } from "@/api/module_rule/rule"; @@ -133,9 +134,10 @@ import { useUserStoreHook } from "@stores"; defineExpose({ loadTree }); +const { loadTree: loadTreeWithOrder, loading } = useRuleCategory(); + const treeRef = ref(); const treeData = ref([]); -const loading = ref(false); const defaultExpandAll = ref(true); const treeProps = { @@ -155,16 +157,7 @@ function filterNode(value: string, data: any) { // 加载树 async function loadTree() { - loading.value = true; - try { - const resp = await RuleCategoryAPI.tree(); - const list = (resp?.data?.data as RuleCategoryNode[]) || []; - treeData.value = Array.isArray(list) ? list : []; - } catch (e) { - treeData.value = []; - } finally { - loading.value = false; - } + treeData.value = await loadTreeWithOrder() } // ============ 当前用户(创建人默认值) ============ diff --git a/src/views/module_rule/rule_list/index.vue b/src/views/module_rule/rule_list/index.vue index a43c9d9..4361834 100644 --- a/src/views/module_rule/rule_list/index.vue +++ b/src/views/module_rule/rule_list/index.vue @@ -200,6 +200,40 @@ + + + + + + + + + + + + + @@ -210,7 +244,7 @@ defineOptions({ name: "RuleList" }); import { ref, reactive, onMounted } from "vue"; import { useRouter } from "vue-router"; -import { ElMessage, ElMessageBox } from "element-plus"; +import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from "element-plus"; import { Plus, Search, Refresh, View } from "@element-plus/icons-vue"; import { RuleAPI } from "@/api/module_rule/rule"; import type { RuleItem, RulePageQuery, RuleStatus, RuleForm } from "@/api/module_rule/rule"; @@ -329,13 +363,52 @@ function handleTest(row: RuleItem) { } // 复制 -async function handleCopy(row: RuleItem) { +const copyDialogVisible = ref(false); +const copySubmitting = ref(false); +const copyFormRef = ref(null); +const copySourceRule = ref(null); +const copyForm = reactive<{ name: string; description: string }>({ + name: "", + description: "", +}); +const copyRules: FormRules = { + name: [ + { required: true, message: "请输入规则名称", trigger: "blur" }, + { max: 128, message: "最多 128 个字符", trigger: "blur" }, + ], +}; + +function handleCopy(row: RuleItem) { + copySourceRule.value = row; + copyForm.name = `${row.name}-副本`; + copyForm.description = row.description || ""; + copyDialogVisible.value = true; +} + +async function handleSubmitCopy() { + if (!copySourceRule.value) return; try { - await RuleAPI.copy(row.id); + await copyFormRef.value?.validate(); + } catch { + return; + } + copySubmitting.value = true; + try { + const src = copySourceRule.value; + const payload: RuleForm = { + name: copyForm.name.trim(), + category_id: src.category_id ?? null, + description: copyForm.description?.trim() || "", + prompt_template: src.prompt_template, + status: src.status, + }; + await RuleAPI.create(payload); ElMessage.success("复制成功"); + copyDialogVisible.value = false; loadList(); } catch (e) { - // 全局拦截器已处理 + } finally { + copySubmitting.value = false; } }