办学质量监测教学评价系统
4398a02bf8543e73a716dee14b3ba4af56c6b9f8..9c4543aca696f4fac00fd83a6b53809d75262eb2
5 小时以前 du
Merge remote-tracking branch 'origin/main'
9c4543 对比 | 目录
5 小时以前 du
流程图
7bf1f4 对比 | 目录
6 小时以前 康鲁杰
页面设计器后端模块创建
3e9c71 对比 | 目录
9 小时以前 康鲁杰
动态页面
0ab0a0 对比 | 目录
9 小时以前 du
页面调整
58a585 对比 | 目录
9 小时以前 du
页面调整
df9702 对比 | 目录
10 小时以前 康鲁杰
动态页面
313331 对比 | 目录
11 小时以前 康鲁杰
创建school-ai业务模块
8aa387 对比 | 目录
已修改6个文件
已添加7个文件
762 ■■■■■ 文件已修改
pom.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/pom.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/pom.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/sc-page-designer/pom.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/sc-services/pom.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/apps/web-antd/package.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/apps/web-antd/src/bootstrap.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/apps/web-antd/src/services/flowableService.js 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/apps/web-antd/src/views/assessment/serviceRating/data.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/apps/web-antd/src/views/assessment/serviceRating/index.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/apps/web-antd/src/views/assessment/serviceRating/serivceDialog.vue 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/apps/web-antd/src/views/system/process/index.vue 472 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/apps/web-antd/src/views/tool/page-designer/index.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -308,7 +308,16 @@
                <artifactId>ruoyi-chat</artifactId>
                <version>${revision}</version>
            </dependency>
            <dependency>
                <groupId>org.ruoyi</groupId>
                <artifactId>sc-services</artifactId>
                <version>${revision}</version>
            </dependency>
            <dependency>
                <groupId>org.ruoyi</groupId>
                <artifactId>sc-page-designer</artifactId>
                <version>${revision}</version>
            </dependency>
            <dependency>
                <groupId>org.ruoyi</groupId>
                <artifactId>ruoyi-knowledge-api</artifactId>
ruoyi-admin/pom.xml
@@ -61,6 +61,16 @@
        <dependency>
            <groupId>org.ruoyi</groupId>
            <artifactId>sc-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.ruoyi</groupId>
            <artifactId>sc-page-designer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.ruoyi</groupId>
            <artifactId>ruoyi-generator</artifactId>
        </dependency>
ruoyi-modules/pom.xml
@@ -21,6 +21,8 @@
        <module>ruoyi-chat</module>
        <module>ruoyi-system</module>
        <module>ruoyi-generator</module>
        <module>sc-services</module>
        <module>sc-page-designer</module>
    </modules>
    <properties>
ruoyi-modules/sc-page-designer/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.ruoyi</groupId>
        <artifactId>ruoyi-modules</artifactId>
        <version>${revision}</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>sc-page-designer</artifactId>
    <description>
        school-ai页面设计器模块
    </description>
    <dependencies>
        <!-- é€šç”¨å·¥å…·-->
        <dependency>
            <groupId>org.ruoyi</groupId>
            <artifactId>ruoyi-common-core</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-modules/sc-services/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.ruoyi</groupId>
        <artifactId>ruoyi-modules</artifactId>
        <version>${revision}</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>sc-services</artifactId>
    <description>
        school-ai业务模块
    </description>
    <dependencies>
    <!-- é€šç”¨å·¥å…·-->
    <dependency>
        <groupId>org.ruoyi</groupId>
        <artifactId>ruoyi-common-core</artifactId>
    </dependency>
    </dependencies>
</project>
ruoyi-ui/apps/web-antd/package.json
@@ -46,14 +46,18 @@
    "@vben/utils": "workspace:*",
    "@vueuse/core": "catalog:",
    "ant-design-vue": "catalog:",
    "axios": "^1.10.0",
    "bpmn-js": "^18.6.2",
    "cropperjs": "^1.6.2",
    "crypto-js": "^4.2.0",
    "dayjs": "catalog:",
    "diagram-js": "^15.3.0",
    "echarts": "^5.5.1",
    "element-plus": "^2.10.2",
    "jsencrypt": "^3.3.2",
    "lodash-es": "^4.17.21",
    "pinia": "catalog:",
    "qs": "^6.13.1",
    "tinymce": "^7.3.0",
    "unplugin-vue-components": "^0.27.3",
    "vue": "catalog:",
ruoyi-ui/apps/web-antd/src/bootstrap.ts
@@ -19,7 +19,10 @@
import { router } from './router';
import formCreate from '@form-create/element-ui';
import FcDesigner from '@form-create/designer';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/reset.css';
async function bootstrap(namespace: string) {
  // åˆå§‹åŒ–组件适配器
  await initComponentAdapter();
@@ -62,6 +65,7 @@
  app.use(ElementPlus);
  app.use(formCreate);
  app.use(FcDesigner);
  app.use(Antd);
  // åŠ¨æ€æ›´æ–°æ ‡é¢˜
  watchEffect(() => {
    if (preferences.app.dynamicTitle) {
ruoyi-ui/apps/web-antd/src/services/flowableService.js
ruoyi-ui/apps/web-antd/src/views/assessment/serviceRating/data.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
import type { VxeGridProps } from 'src/adapter/vxe-table';
import type { FormSchemaGetter } from "src/adapter/form";
export const querySchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    fieldName: 'roleName',
    label: '名称',
  },
  {
    component: 'Select',
    fieldName: 'roleSort',
    label: '创建人',
  },
  {
    component: 'RangePicker',
    fieldName: 'createTime',
    label: '创建时间',
  },
];
export const columns: VxeGridProps['columns'] = [
  { type: 'checkbox', width: 60 },
  {
    title: '名称',
    field: 'roleName',
  },
  {
    title: '创建人',
    field: 'roleSort',
  },
  {
    title: '创建时间',
    field: 'createTime',
  },
  {
    field: 'action',
    fixed: 'right',
    slots: { default: 'action' },
    title: '操作',
    width: 180,
  },
];
ruoyi-ui/apps/web-antd/src/views/assessment/serviceRating/index.vue
@@ -1,10 +1,92 @@
<template>
<div>工作考核指标</div>
  <Page :auto-content-height="true">
    <BasicTable table-title="工作考核指标列表">
      <template #toolbar-tools>
        <Space>
          <a-button
            v-access:code="['system:role:export']"
            @click="handleDownloadExcel"
            style="margin-right: 10px"
          >
            {{ $t('pages.common.export') }}
          </a-button>
          <a-button
            type="primary"
            v-access:code="['system:role:add']"
            @click="handleAdd"
          >
            {{ $t('pages.common.add') }}
          </a-button>
        </Space>
      </template>
    </BasicTable>
  </Page>
</template>
<script>
export default {
  name: "index"
<script setup lang="ts">
import type { VxeGridProps } from "#/adapter/vxe-table";
import { useVbenVxeGrid, vxeCheckboxChecked } from '#/adapter/vxe-table';
import type { VbenFormProps } from '@vben/common-ui';
import type { roleList} from "#/api/system/role";
import { columns, querySchema } from './data';
import { Page, useVbenDrawer, useVbenModal } from '@vben/common-ui';
const formOptions: VbenFormProps = {
  commonConfig: {
    labelWidth: 80,
    componentProps: {
      allowClear: true,
    },
  },
  schema: querySchema(),
  wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4',
  // æ—¥æœŸé€‰æ‹©æ ¼å¼åŒ–
  fieldMappingTime: [
    [
      'createTime',
      ['params[beginTime]', 'params[endTime]'],
      ['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59'],
    ],
  ],
};
const gridOptions: VxeGridProps = {
  checkboxConfig: {
    // é«˜äº®
    highlight: true,
    // ç¿»é¡µæ—¶ä¿ç•™é€‰ä¸­çŠ¶æ€
    reserve: true,
    // ç‚¹å‡»è¡Œé€‰ä¸­
    // trigger: 'row',
    checkMethod: ({ row }) => row.roleId !== 1,
  },
  columns,
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues = {}) => {
        return await roleList({
          pageNum: page.currentPage,
          pageSize: page.pageSize,
          ...formValues,
        });
      },
    },
  },
  rowConfig: {
    keyField: 'roleId',
  },
  id: 'system-role-index',
};
const [BasicTable,tableApi] = useVbenVxeGrid({
  formOptions,
  gridOptions,
});
const handleAdd = () => {
  console.log('新增')
}
const handleDownloadExcel = () => {
  console.log('导出')
}
</script>
ruoyi-ui/apps/web-antd/src/views/assessment/serviceRating/serivceDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
<script>
import {modelInfo} from "#/api/system/model/index.js";
import {pick} from "lodash-es";
import {useVbenModal} from "@vben/common-ui";
import {ref, computed} from "vue";
import { $t } from '@vben/locales';
const defaultValues = {
  id: undefined,
  name: undefined,
}
const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? $t('编辑') : $t('新增');
});
const { validate, validateInfos, resetFields } = Form.useForm(
  formData,
  formRules,
);
const [BasicModal, modalApi] = useVbenModal({
  class: 'w-[550px]',
  fullscreenButton: false,
  closeOnClickModal: false,
  onClosed: handleCancel,
  onConfirm: handleConfirm,
  onOpenChange: async (isOpen) => {
    if (!isOpen) {
      return null;
    }
    modalApi.modalLoading(true);
    const { id } = modalApi.getData() as { id?: number | string };
    isUpdate.value = !!id;
    if (isUpdate.value && id) {
      const record = await modelInfo(id);
      // åªèµ‹å€¼å­˜åœ¨çš„字段
      const filterRecord = pick(record, Object.keys(defaultValues));
      formData.value = filterRecord;
    }
    modalApi.modalLoading(false);
  },
});
</script>
<template>
  <BasicModal :title="title">
    <Form :label-col="{ span: 4 }">
      <FormItem label="名称" v-bind="validateInfos.name">
        <Input
          v-model:value="formData.name"
          :placeholder="$t('ui.formRules.required')"
        />
      </FormItem>
    </Form>
  </BasicModal>
</template>
<style scoped>
</style>
ruoyi-ui/apps/web-antd/src/views/system/process/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,472 @@
<template>
  <div class="process-definition-container">
    <a-card title="流程定义列表" :bordered="false">
      <div class="table-actions">
        <a-button type="primary" @click="showCreateModal">新增流程图</a-button>
      </div>
      <a-table
        :columns="columns"
        :data-source="definitions"
        :row-key="record => record.id"
        :pagination="pagination"
        :loading="loading"
        @change="handleTableChange"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'action'">
            <a-space>
              <a-button type="link" @click="showDiagram(record)">查看</a-button>
              <a-button type="link" @click="editDiagram(record)">修改</a-button>
              <a-button type="link" danger @click="deleteDefinition(record)">删除</a-button>
            </a-space>
          </template>
        </template>
      </a-table>
    </a-card>
    <!-- æµç¨‹å›¾æŸ¥çœ‹æ¨¡æ€æ¡† -->
    <a-modal
      v-model:visible="diagramVisible"
      title="流程图查看"
      width="80%"
      :footer="null"
      @cancel="handleDiagramCancel"
    >
      <div style="text-align: center">
        <img
          v-if="currentDiagramUrl"
          :src="currentDiagramUrl"
          alt="流程图"
          style="max-width: 100%"
        />
        <a-skeleton v-else active />
      </div>
    </a-modal>
    <!-- æµç¨‹å›¾ç¼–辑模态框 -->
    <a-modal
      v-model:visible="editorVisible"
      :title="editorTitle"
      width="90%"
      :maskClosable="false"
      :okText="'保存'"
      :cancelText="'取消'"
      :confirmLoading="editorSaving"
      @ok="handleEditorOk"
      @cancel="handleEditorCancel"
      :destroyOnClose="true"
      :afterClose="handleEditorAfterClose"
      :style="{ top: '20px' }"
      :bodyStyle="{
      padding: '0',
      height: 'calc(100vh - 100px)',
      overflow: 'hidden',
      display: 'flex',
      flexDirection: 'column'
    }"
    >
      <div class="editor-container">
        <div v-if="isCreateMode" class="create-form">
          <a-form layout="vertical">
            <a-form-item label="流程名称" required>
              <a-input v-model:value="newProcess.name" placeholder="请输入流程名称" />
            </a-form-item>
            <a-form-item label="流程Key" required>
              <a-input v-model:value="newProcess.key" placeholder="请输入流程Key" />
            </a-form-item>
            <a-form-item label="流程描述">
              <a-textarea v-model:value="newProcess.description" placeholder="请输入流程描述" />
            </a-form-item>
          </a-form>
        </div>
        <div class="bpmn-editor" ref="bpmnEditor"></div>
      </div>
    </a-modal>
  </div>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { message, Modal } from 'ant-design-vue'
import BpmnModeler from 'bpmn-js/lib/Modeler'
import 'bpmn-js/dist/assets/diagram-js.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-js.css'
// è¡¨æ ¼åˆ—定义
const columns = [
  {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    ellipsis: true
  },
  {
    title: '名称',
    dataIndex: 'name',
    key: 'name'
  },
  {
    title: 'Key',
    dataIndex: 'key',
    key: 'key'
  },
  {
    title: '操作',
    key: 'action',
  }
]
// æ•°æ®çŠ¶æ€
const definitions = ref([])
const loading = ref(false)
const pagination = ref({
  current: 1,
  pageSize: 10,
  total: 0,
  showSizeChanger: true,
  pageSizeOptions: ['10', '20', '50']
})
// æµç¨‹å›¾æŸ¥çœ‹ç›¸å…³çŠ¶æ€
const diagramVisible = ref(false)
const currentDiagramUrl = ref('')
const currentProcessDefinition = ref(null)
// æµç¨‹å›¾ç¼–辑相关状态
const editorVisible = ref(false)
const editorSaving = ref(false)
const editorTitle = ref('流程图编辑')
const bpmnModeler = ref(null)
const bpmnEditor = ref(null)
const isCreateMode = ref(false)
const newProcess = ref({
  name: '',
  key: '',
  description: ''
})
// èŽ·å–æµç¨‹å®šä¹‰åˆ—è¡¨
const fetchProcessDefinitions = async (params = {}) => {
  loading.value = true
  try {
    // æ¨¡æ‹Ÿæ•°æ®
    const mockData = [
      { id: '1', name: '请假流程', key: 'leaveProcess'},
      { id: '2', name: '报销流程', key: 'expenseProcess'},
      { id: '3', name: '采购流程', key: 'purchaseProcess' }
    ]
    // æ¨¡æ‹Ÿåˆ†é¡µ
    const start = (params.page - 1) * params.size
    const end = start + params.size
    definitions.value = mockData.slice(start, end)
    pagination.value.total = mockData.length
  } catch (error) {
    message.error('加载流程定义失败:'+ error.message)
  } finally {
    loading.value = false
  }
}
// è¡¨æ ¼åˆ†é¡µ/排序变化处理
const handleTableChange = (pag, filters, sorter) => {
  const params = {
    page: pag.current,
    size: pag.pageSize
  }
  if (sorter.field) {
    params.sort = sorter.field
    params.order = sorter.order === 'ascend' ? 'asc' : 'desc'
  }
  fetchProcessDefinitions(params)
}
// æ˜¾ç¤ºæµç¨‹å›¾
const showDiagram = (record) => {
  currentProcessDefinition.value = record
  currentDiagramUrl.value = `https://via.placeholder.com/800x600?text=流程图+${record.id}`
  diagramVisible.value = true
}
// é”€æ¯BPMN编辑器
const destroyBpmnEditor = () => {
  if (bpmnModeler.value) {
    bpmnModeler.value.destroy()
    bpmnModeler.value = null
  }
}
// åˆå§‹åŒ–BPMN编辑器
const initBpmnEditor = async (xml) => {
  await nextTick()
  // å…ˆé”€æ¯æ—§çš„编辑器
  destroyBpmnEditor()
  try {
    // åˆ›å»ºæ–°çš„编辑器实例
    bpmnModeler.value = new BpmnModeler({
      container: bpmnEditor.value,
    })
    // åŠ è½½XML或默认流程图
    const diagram = xml || `
      <?xml version="1.0" encoding="UTF-8"?>
      <bpmn:definitions
        xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
        xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
        xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
        xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
        id="Definitions_1"
        targetNamespace="http://bpmn.io/schema/bpmn">
        <bpmn:process id="Process_1" isExecutable="false">
          <bpmn:startEvent id="StartEvent_1" />
        </bpmn:process>
        <bpmndi:BPMNDiagram id="BPMNDiagram_1">
          <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
            <bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
              <dc:Bounds x="173" y="102" width="36" height="36" />
            </bpmndi:BPMNShape>
          </bpmndi:BPMNPlane>
        </bpmndi:BPMNDiagram>
      </bpmn:definitions>
    `
    await bpmnModeler.value.importXML(diagram)
  } catch (err) {
    console.error('Error rendering diagram', err)
    message.error('初始化流程图编辑器失败: ' + err.message)
  }
}
// æ˜¾ç¤ºåˆ›å»ºæ–°æµç¨‹æ¨¡æ€æ¡†
const showCreateModal = () => {
  isCreateMode.value = true
  editorTitle.value = '创建新流程图'
  editorVisible.value = true
  // é‡ç½®è¡¨å•
  newProcess.value = {
    name: '',
    key: '',
    description: ''
  }
  // åˆå§‹åŒ–编辑器
  initBpmnEditor()
}
// ç¼–辑流程图
const editDiagram = async (record) => {
  isCreateMode.value = false
  currentProcessDefinition.value = record
  editorTitle.value = `编辑流程 - ${record.name}`
  editorVisible.value = true
  // æ¨¡æ‹ŸåŠ è½½æµç¨‹å®šä¹‰XML
  const mockXml = `
    <?xml version="1.0" encoding="UTF-8"?>
    <bpmn:definitions
      xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
      xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
      xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
      xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
      id="Definitions_1"
      targetNamespace="http://bpmn.io/schema/bpmn">
      <bpmn:process id="${record.id}" name="${record.name}" isExecutable="true">
        <bpmn:startEvent id="StartEvent_1" name="开始" />
        <bpmn:userTask id="UserTask_1" name="提交申请" />
        <bpmn:sequenceFlow id="Flow_1" sourceRef="StartEvent_1" targetRef="UserTask_1" />
        <bpmn:endEvent id="EndEvent_1" name="结束" />
        <bpmn:sequenceFlow id="Flow_2" sourceRef="UserTask_1" targetRef="EndEvent_1" />
      </bpmn:process>
      <bpmndi:BPMNDiagram id="BPMNDiagram_1">
        <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="${record.id}">
          <bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
            <dc:Bounds x="173" y="102" width="36" height="36" />
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape id="UserTask_1_di" bpmnElement="UserTask_1">
            <dc:Bounds x="280" y="80" width="100" height="80" />
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape id="EndEvent_1_di" bpmnElement="EndEvent_1">
            <dc:Bounds x="450" y="102" width="36" height="36" />
          </bpmndi:BPMNShape>
          <bpmndi:BPMNEdge id="Flow_1_di" bpmnElement="Flow_1">
            <di:waypoint x="209" y="120" />
            <di:waypoint x="280" y="120" />
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge id="Flow_2_di" bpmnElement="Flow_2">
            <di:waypoint x="380" y="120" />
            <di:waypoint x="450" y="120" />
          </bpmndi:BPMNEdge>
        </bpmndi:BPMNPlane>
      </bpmndi:BPMNDiagram>
    </bpmn:definitions>
  `
  // åˆå§‹åŒ–编辑器并加载XML
  initBpmnEditor(mockXml)
}
// ä¿å­˜æµç¨‹å›¾ä¿®æ”¹
const handleEditorOk = async () => {
  editorSaving.value = true
  try {
    if (isCreateMode.value) {
      // éªŒè¯è¡¨å•
      if (!newProcess.value.name || !newProcess.value.key) {
        message.error('请填写流程名称和Key')
        return
      }
      // èŽ·å–XML
      const { xml } = await bpmnModeler.value.saveXML({ format: true })
      console.log('新流程XML:', xml)
      // æ¨¡æ‹Ÿåˆ›å»ºæ–°æµç¨‹
      await new Promise(resolve => setTimeout(resolve, 1000))
      // æ·»åŠ åˆ°åˆ—è¡¨
      const newId = Math.max(...definitions.value.map(d => parseInt(d.id))) + 1
      definitions.value.unshift({
        id: newId.toString(),
        name: newProcess.value.name,
        key: newProcess.value.key,
        version: 1
      })
      message.success('新流程创建成功')
    } else {
      // èŽ·å–ä¿®æ”¹åŽçš„XML
      const { xml } = await bpmnModeler.value.saveXML({ format: true })
      console.log('修改后的XML:', xml)
      // æ¨¡æ‹Ÿä¿å­˜
      await new Promise(resolve => setTimeout(resolve, 1000))
      message.success('流程图保存成功')
    }
    editorVisible.value = false
  } catch (error) {
    console.error('Error saving BPMN diagram', error)
    message.error('操作失败: ' + error.message)
  } finally {
    editorSaving.value = false
  }
}
// åˆ é™¤æµç¨‹å®šä¹‰
const deleteDefinition = (record) => {
  Modal.confirm({
    title: '确认删除流程?',
    content: `确定要删除流程 "${record.name}" å—?此操作不可恢复。`,
    okText: '确认',
    okType: 'danger',
    cancelText: '取消',
    onOk() {
      // æ¨¡æ‹Ÿåˆ é™¤
      definitions.value = definitions.value.filter(item => item.id !== record.id)
      message.success('流程删除成功')
    }
  })
}
// æ¨¡æ€æ¡†å…³é—­åŽæ¸…理
const handleEditorAfterClose = () => {
  destroyBpmnEditor()
}
const handleEditorCancel = () => {
  editorVisible.value = false
}
const handleDiagramCancel = () => {
  diagramVisible.value = false
}
// åˆå§‹åŒ–加载数据
onMounted(() => {
  const params = {
    page: 1,
    size: 10
  }
  fetchProcessDefinitions(params)
})
</script>
<style scoped>
.process-definition-container {
  padding: 20px;
  background: #fff;
}
.table-actions {
  margin-bottom: 16px;
  display: flex;
  justify-content: flex-end;
}
.editor-container {
  height: 600px;
  display: flex;
  flex-direction: column;
}
.bpmn-editor {
  flex: 1;
  border: 1px solid #d9d9d9;
  border-radius: 2px;
  margin-top: 16px;
  min-height: 500px; /* ç¡®ä¿ç¼–辑器有足够高度 */
}
.create-form {
  padding: 16px;
  background: #fafafa;
  border-radius: 2px;
  border: 1px solid #d9d9d9;
  margin-bottom: 16px;
}
/* éšè—BPMN水印 */
.bpmn-editor :deep(.bjs-powered-by) {
  display: none !important;
}
.editor-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}
.bpmn-editor {
  flex: 1;
  min-height: 0; /* é‡è¦ï¼šå…è®¸flex容器收缩 */
  border: 1px solid #d9d9d9;
  border-radius: 2px;
  margin-top: 16px;
}
.create-form {
  padding: 16px;
  background: #fafafa;
  border-radius: 2px;
  border: 1px solid #d9d9d9;
  margin-bottom: 16px;
}
/* éšè—BPMN水印 */
.bpmn-editor :deep(.bjs-powered-by) {
  display: none !important;
}
/* ç¡®ä¿BPMN工具栏可见 */
.bpmn-editor :deep(.djs-palette) {
  top: 20px;
  left: 20px;
}
</style>
ruoyi-ui/apps/web-antd/src/views/tool/page-designer/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
<template>
  <div>111</div>
</template>
<script>
export default {
  name: "index"
}
</script>
<style scoped>
</style>