Bläddra i källkod

feat(代码生成器-生成代码): 生成代码功能完善

shizhongming 2 år sedan
förälder
incheckning
1026bb8b30

+ 11 - 6
src/components/Form/src/smart-boot/components/base/SmartTableSelect.tsx

@@ -1,6 +1,7 @@
 import type { SmartTableProps } from '@/components/SmartTable';
 
 import { defineComponent, ref } from 'vue';
+import { Row, Col } from 'ant-design-vue';
 
 import { propTypes } from '@/utils/propTypes';
 import { useModal } from '@/components/Modal';
@@ -11,6 +12,10 @@ import './SmartTableSelect.less';
 
 export default defineComponent({
   name: 'SmartTableSelect',
+  components: {
+    Row,
+    Col,
+  },
   props: {
     // 是否支持多选
     multiple: propTypes.bool.def(true),
@@ -82,8 +87,8 @@ export default defineComponent({
     };
     return (
       <div class="smart-table-select">
-        <a-row type="flex" gutter={8}>
-          <a-col class="select">
+        <Row type="flex" gutter={8}>
+          <Col class="select">
             <a-select
               {...$attrs}
               size={size}
@@ -95,8 +100,8 @@ export default defineComponent({
               onDeselect={handleDeselect}
               mode={multiple ? 'multiple' : 'combobox'}
             ></a-select>
-          </a-col>
-          <a-col class="button">
+          </Col>
+          <Col class="button">
             <a-button
               disabled={disabled}
               size={size}
@@ -105,8 +110,8 @@ export default defineComponent({
             >
               {$t('common.button.choose')}
             </a-button>
-          </a-col>
-        </a-row>
+          </Col>
+        </Row>
         <SmartTableSelectModal
           {...$attrs}
           onRegister={registerModal}

+ 1 - 1
src/components/SmartTable/src/types/SmartTableType.ts

@@ -128,7 +128,7 @@ export interface TableActionType {
   getShowPagination: () => boolean;
 
   deleteByCheckbox: () => void;
-  getCheckboxRecords: (isFull: boolean) => Array<any>;
+  getCheckboxRecords: (isFull?: boolean) => Array<any>;
   getRadioRecord: (isFull: boolean) => any;
 
   // openAddEditModal: <T = any>(props?: boolean, data?: T, openOnSet?: boolean) => void

+ 2 - 0
src/components/registerGlobComp.ts

@@ -11,6 +11,7 @@ import {
   Tabs,
   Switch,
   Form,
+  Checkbox,
   InputNumber,
 } from 'ant-design-vue';
 import VXETable from 'vxe-table';
@@ -46,5 +47,6 @@ export function registerGlobComp(app: App) {
     .use(Switch)
     .use(InputNumber)
     .use(Form)
+    .use(Checkbox)
     .use(VXETable);
 }

+ 5 - 2
src/modules/codeGenerator/components/template/TemplateGroup.vue

@@ -8,12 +8,13 @@
       @cell-click="handleCellClick"
     >
       <template #table-groupName="{ row }">
-        <div style="cursor: pointer" @contextmenu="(e) => handleContext(e, row)">
+        <div v-if="editable" style="cursor: pointer" @contextmenu="(e) => handleContext(e, row)">
           {{ row.groupName }}
         </div>
+        <span v-else>{{ row.groupName }}</span>
       </template>
     </SmartTable>
-    <div class="button-container">
+    <div class="button-container" v-if="editable">
       <a-button class="button" block type="primary" @click="() => showAddModal()">
         {{ $t('common.button.add') }}
       </a-button>
@@ -38,9 +39,11 @@
     deleteGroupByIdApi,
     getGroupByIdApi,
   } from '../../views/template/CodeTemplateList.api';
+  import { propTypes } from '@/utils/propTypes';
 
   const props = defineProps({
     tableProps: Object as PropType<SmartTableProps>,
+    editable: propTypes.bool.def(true),
   });
 
   const emit = defineEmits(['change']);

+ 8 - 0
src/modules/codeGenerator/types/index.ts

@@ -0,0 +1,8 @@
+export interface CodeCreatedModel {
+  mainId: number;
+  className: string;
+  description?: string;
+  packages: string;
+  templateIdList: number[];
+  controllerBasePath?: string;
+}

+ 0 - 11
src/modules/codeGenerator/views/codeCreate/CodeCreateSupport.ts

@@ -1,11 +0,0 @@
-/**
- * 扩展名类型映射
- */
-export const extensionLanguageMap: any = {
-  'text/x-java': 'java',
-  xml: 'xml',
-  javascript: 'js',
-  html: 'html',
-  'text/x-vue': 'vue',
-  typescript: 'ts',
-};

+ 1 - 1
src/modules/codeGenerator/views/codeCreate/CodeCreateView.vue

@@ -14,9 +14,9 @@
 <script setup lang="ts">
   import { onMounted, ref, useAttrs } from 'vue';
   import { downloadByData } from '@/utils/file/download';
-  import { extensionLanguageMap } from './CodeCreateSupport';
   import { CodeEditor } from '@/components/CodeEditor';
   import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
+  import { extensionLanguageMap } from '@/modules/codeGenerator/constants/Constants';
 
   const attrs = useAttrs();
   const data = ref<Array<any>>([]);

+ 0 - 80
src/modules/codeGenerator/views/codeCreate/CodeCreateViewOld.vue

@@ -1,80 +0,0 @@
-<template>
-  <div class="full-height" style=" height: 100%;padding: 10px">
-    <div style="padding-bottom: 6px">
-      <a-button type="primary" @click="handleDownloadAll">下载全部</a-button>
-    </div>
-    <a-tabs class="code-container">
-      <a-tab-pane v-for="item in data" :key="item.templateId" :tab="item.templateName">
-        <CodeEditor read-only :mode="item.language" :code="item.code" />
-      </a-tab-pane>
-    </a-tabs>
-  </div>
-</template>
-
-<script lang="ts">
-  import { defineComponent, onMounted, ref } from 'vue';
-
-  import { CodeEditor } from '@/components/CodeEditor';
-
-  import { downloadByData } from '@/utils/file/download';
-
-  import { extensionLanguageMap } from './CodeCreateSupport';
-  import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
-
-  /**
-   * 代码生成页面
-   */
-  export default defineComponent({
-    name: 'CodeCreateView',
-    components: {
-      CodeEditor,
-    },
-    // @ts-ignore
-    setup(props, { attrs }: any) {
-      const data = ref<Array<any>>([]);
-      const dataLoading = ref(false);
-      /**
-       * 加载数据函数
-       */
-      const loadData = async () => {
-        dataLoading.value = true;
-        try {
-          data.value = await defHttp.post({
-            service: ApiServiceEnum.SMART_CODE,
-            url: 'db/code/main/createCode',
-            data: Object.assign({}, attrs, {
-              templateIdList: attrs.templateIdList.split(','),
-            }),
-          });
-        } finally {
-          dataLoading.value = false;
-        }
-      };
-      /**
-       * 下载全部
-       */
-      const handleDownloadAll = () => {
-        data.value.forEach((item): any => {
-          const filename = `${item.filename}.${extensionLanguageMap[item.language]}`;
-          downloadByData(item.code, filename);
-        });
-      };
-      onMounted(loadData);
-      return {
-        data,
-        handleDownloadAll,
-      };
-    },
-  });
-</script>
-
-<style lang="less" scoped>
-  .code-container {
-    height: calc(100% - 38px);
-    border: 1px solid gainsboro;
-
-    ::v-deep(.ant-tabs-content) {
-      height: calc(100% - 60px);
-    }
-  }
-</style>

+ 1 - 1
src/modules/codeGenerator/views/codeDesign/componenets/DatabaseSelect/DatabaseSelect.vue

@@ -37,7 +37,7 @@
         });
         data.value = result.map((item: any) => {
           return {
-            key: item.id + '',
+            key: item.id,
             value: item.connectionName,
           };
         });

+ 1 - 1
src/modules/codeGenerator/views/codeDesign/componenets/PageTableSetting/PageTableSetting.vue

@@ -15,7 +15,7 @@
         <a-checkbox v-model:checked="row.sortable" :size="formSizeConfig" />
       </template>
       <template #table-fixed="{ row }">
-        <a-select v-model:value="row.fixed" :size="formSizeConfig" style="width: 100px">
+        <a-select v-model:value="row.fixed" :size="formSizeConfig" allow-clear style="width: 100px">
           <a-select-option value="left">left</a-select-option>
           <a-select-option value="right">right</a-select-option>
         </a-select>

+ 20 - 13
src/modules/codeGenerator/views/codeList/components/CodeCreateModal.vue

@@ -12,6 +12,7 @@
           v-model:value="model.templateIdList"
           :table-props="{}"
           title="选择模板"
+          allow-clear
           defaultFullscreen
           multiple
           :list-api="listByIdApi"
@@ -28,36 +29,41 @@
         </SmartTableSelect>
       </template>
     </BasicForm>
+    <CodeCreatedResultModal @register="registerResultModal" />
   </BasicModal>
 </template>
 
 <script lang="ts" setup>
   import { useI18n } from '@/hooks/web/useI18n';
-  import { useRouter } from 'vue-router';
-  import { message } from 'ant-design-vue';
+  // import { useRouter } from 'vue-router';
   import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
 
-  import { BasicModal, useModalInner } from '@/components/Modal';
+  import { BasicModal, useModalInner, useModal } from '@/components/Modal';
   import { BasicForm, useForm, SmartTableSelect } from '@/components/Form';
   import TemplateSelectTable from './TemplateSelectTable.vue';
+  import { warnMessage } from '@/utils/message/SystemNotice';
+  import CodeCreatedResultModal from './CodeCreatedResultModal.vue';
 
-  const router = useRouter();
+  // const router = useRouter();
   const { t } = useI18n();
 
+  const [registerResultModal, { openModal }] = useModal();
+
   const handleOk = async () => {
     const model = await validate();
     const templateIdList = model.templateIdList;
     if (!templateIdList || templateIdList.length === 0) {
-      message.warn(t('generator.views.codeCreateForm.message.choseTemplate'));
+      warnMessage(t('generator.views.codeCreateForm.message.choseTemplate'));
     }
-    const url = router.resolve({
-      path: '/codeCreateView',
-      query: {
-        ...model,
-        templateIdList: templateIdList.join(','),
-      },
-    });
-    window.open(url.href, '_blank');
+    openModal(true, model);
+    // const url = router.resolve({
+    //   path: '/codeCreateView',
+    //   query: {
+    //     ...model,
+    //     templateIdList: templateIdList.join(','),
+    //   },
+    // });
+    // window.open(url.href, '_blank');
   };
 
   const [registerModal] = useModalInner((codeConfigData: Recordable) => {
@@ -67,6 +73,7 @@
       tableName,
       className,
       mainId: id,
+      templateIdList: [],
     });
   });
 

+ 71 - 0
src/modules/codeGenerator/views/codeList/components/CodeCreatedResultModal.vue

@@ -0,0 +1,71 @@
+<template>
+  <BasicModal
+    title="生成代码"
+    defaultFullscreen
+    :wrapClassName="prefixCls"
+    @register="registerModal"
+    @ok="handleDownloadAll"
+    okText="下载全部"
+  >
+    <a-tabs class="full-height">
+      <a-tab-pane v-for="item in dataRef" :key="item.templateId" :tab="item.templateName">
+        <CodeEditor readonly :value="item.code" />
+      </a-tab-pane>
+    </a-tabs>
+  </BasicModal>
+</template>
+<script setup lang="ts">
+  import type { CodeCreatedModel } from '@/modules/codeGenerator/types';
+
+  import { BasicModal, useModalInner } from '@/components/Modal';
+  import { ref } from 'vue';
+  import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
+  import { CodeEditor } from '@/components/CodeEditor';
+  import { useDesign } from '@/hooks/web/useDesign';
+  import { extensionLanguageMap } from '@/modules/codeGenerator/constants/Constants';
+  import { downloadByData } from '@/utils/file/download';
+
+  const { prefixCls } = useDesign('smart-tool-code-codeCreateResult');
+
+  const [registerModal, { changeLoading, closeModal }] = useModalInner((data: CodeCreatedModel) => {
+    loadData(data);
+  });
+  const dataRef = ref<Array<any>>([]);
+
+  /**
+   * 加载数据函数
+   */
+  const loadData = async (data: CodeCreatedModel) => {
+    try {
+      changeLoading(true);
+      dataRef.value = await defHttp.post({
+        service: ApiServiceEnum.SMART_CODE,
+        url: 'db/code/main/createCode',
+        data,
+      });
+    } finally {
+      changeLoading(false);
+    }
+  };
+
+  /**
+   * 下载全部
+   */
+  const handleDownloadAll = () => {
+    dataRef.value.forEach((item): any => {
+      const filename = `${item.filename}.${extensionLanguageMap[item.language]}`;
+      downloadByData(item.code, filename);
+    });
+    closeModal();
+  };
+</script>
+
+<style lang="less">
+  @prefix-cls: ~'@{namespace}-smart-tool-code-codeCreateResult';
+
+  .@{prefix-cls} {
+    .ant-tabs-content {
+      height: 100%;
+    }
+  }
+</style>

+ 99 - 80
src/modules/codeGenerator/views/codeList/components/TemplateSelectTable.vue

@@ -1,13 +1,14 @@
 <template>
   <LayoutSeparate first-size="200px" :show-line="false" class="full-height">
     <template #first>
-      <TemplateGroup class="full-height" @current-change="handleCurrentChange" />
+      <TemplateGroup class="full-height" @change="handleCurrentChange" :editable="false" />
     </template>
     <template #second>
       <SmartTable
         @register="registerTable"
         @checkbox-change="handleCheckboxChange"
         @proxy-query="resetCheckbox"
+        @checkbox-all="handleCheckboxAll"
       />
     </template>
   </LayoutSeparate>
@@ -16,7 +17,6 @@
 <script lang="ts" setup>
   import { useI18n } from '@/hooks/web/useI18n';
   import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
-  import { merge } from 'lodash-es';
 
   import { SmartTable, useSmartTable } from '@/components/SmartTable';
   import { LayoutSeparate } from '@/components/LayoutSeparate';
@@ -37,10 +37,10 @@
   });
   const { t } = useI18n();
 
-  let currentGroup: Recordable = {};
+  let currentGroupId: number | null = null;
 
-  const handleCurrentChange = (row) => {
-    currentGroup = row || {};
+  const handleCurrentChange = (groupId) => {
+    currentGroupId = groupId;
     query();
   };
 
@@ -52,10 +52,20 @@
     }
   };
 
+  const handleCheckboxAll = ({ checked }) => {
+    const selectRows = getCheckboxRecords();
+    if (checked) {
+      props.removeSelectData(props.selectData);
+      props.addSelectData(selectRows);
+    } else {
+      props.removeSelectData(props.selectData);
+    }
+  };
+
   const resetCheckbox = async () => {
     // 数据重新加载后,设置选中的数据
-    await getTableInstance().setAllCheckboxRow(false);
-    await setCheckboxRow(props.selectData, true);
+    getTableInstance().setAllCheckboxRow(false);
+    setCheckboxRow(props.selectData, true);
   };
 
   watch(
@@ -65,86 +75,95 @@
     },
   );
 
-  const [registerTable, { query, getTableInstance, setCheckboxRow }] = useSmartTable({
-    useSearchForm: true,
-    height: 'auto',
-    pagerConfig: true,
-    rowConfig: {
-      keyField: 'templateId',
-    },
-    proxyConfig: {
-      ajax: {
-        query: (params) => {
-          const parameter = merge(params.ajaxParameter, {
-            parameter: {
-              'groupId@=': currentGroup.groupId,
-            },
-          });
-          return defHttp.post({
-            service: ApiServiceEnum.SMART_CODE,
-            url: 'db/code/template/list',
-            data: parameter,
-          });
-        },
+  const [registerTable, { query, getTableInstance, setCheckboxRow, getCheckboxRecords }] =
+    useSmartTable({
+      useSearchForm: true,
+      height: 'auto',
+      pagerConfig: true,
+      rowConfig: {
+        keyField: 'templateId',
       },
-    },
-    searchFormConfig: {
-      colon: true,
-      layout: 'inline',
-      baseColProps: {
-        span: 12,
+      showOverflow: 'tooltip',
+      checkboxConfig: {
+        rowTrigger: 'multiple',
+        highlight: true,
+      },
+      proxyConfig: {
+        ajax: {
+          query: ({ ajaxParameter }) => {
+            let parameter = {};
+            if (currentGroupId != null) {
+              parameter = { 'groupId@=': currentGroupId };
+            }
+            return defHttp.post({
+              service: ApiServiceEnum.SMART_CODE,
+              url: 'db/code/template/list',
+              data: {
+                ...ajaxParameter,
+                parameter: {
+                  ...ajaxParameter?.parameter,
+                  ...parameter,
+                },
+              },
+            });
+          },
+        },
       },
-      actionColOptions: {
-        span: 12,
+      searchFormConfig: {
+        colon: true,
+        layout: 'inline',
+        actionColOptions: {
+          span: undefined,
+        },
+        compact: true,
+        schemas: [
+          {
+            label: t('generator.views.template.table.name'),
+            field: 'name',
+            component: 'Input',
+          },
+        ],
       },
-      schemas: [
+      columns: [
+        {
+          type: 'checkbox',
+          width: 60,
+          fixed: 'left',
+        },
         {
-          label: t('generator.views.template.table.name'),
           field: 'name',
-          component: 'Input',
+          title: '{generator.views.template.table.name}',
+          width: 200,
+          fixed: 'left',
+          align: 'left',
+          headerAlign: 'center',
         },
-      ],
-    },
-    columns: [
-      {
-        type: 'checkbox',
-        width: 60,
-        fixed: 'left',
-      },
-      {
-        field: 'name',
-        title: '{generator.views.template.table.name}',
-        width: 200,
-        fixed: 'left',
-        align: 'left',
-        headerAlign: 'center',
-      },
-      {
-        field: 'templateType',
-        title: '{generator.views.template.table.templateType}',
-        width: 140,
-        formatter: ({ row }: any) => {
-          const templateType = templateTypeConstants[row.templateType];
-          if (templateType) {
-            return t(templateType.label);
-          }
-          return '';
+        {
+          field: 'templateType',
+          title: '{generator.views.template.table.templateType}',
+          width: 140,
+          formatter: ({ row }: any) => {
+            const templateType = templateTypeConstants[row.templateType];
+            if (templateType) {
+              return t(templateType.label);
+            }
+            return '';
+          },
         },
-      },
-      {
-        field: 'language',
-        title: '{generator.views.template.table.language}',
-        width: 200,
-      },
-      {
-        field: 'remark',
-        title: '{generator.views.template.table.remark}',
-        minWidth: 200,
-        align: 'left',
-        headerAlign: 'center',
-      },
-    ],
-  });
+        {
+          field: 'language',
+          title: '{generator.views.template.table.language}',
+          width: 200,
+        },
+        {
+          field: 'remark',
+          title: '{generator.views.template.table.remark}',
+          minWidth: 200,
+          align: 'left',
+          headerAlign: 'center',
+        },
+      ],
+    });
 </script>
 
 <style scoped></style>

+ 10 - 2
src/router/helper/routeHelper.ts

@@ -1,5 +1,5 @@
 import type { AppRouteModule, AppRouteRecordRaw } from '@/router/types';
-import type { Router, RouteRecordNormalized } from 'vue-router';
+import type { RouteLocationNormalized, Router, RouteRecordNormalized } from 'vue-router';
 
 import { getParentLayout, LAYOUT, EXCEPTION_COMPONENT } from '@/router/constant';
 import { cloneDeep, omit } from 'lodash-es';
@@ -24,7 +24,7 @@ function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) {
     if (!item.component && item.meta?.frameSrc) {
       item.component = 'IFRAME';
     }
-    const { component, name } = item;
+    const { component, name, meta } = item;
     const { children } = item;
     if (component) {
       const layoutFound = LayoutMap.get(component.toUpperCase());
@@ -36,6 +36,14 @@ function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) {
     } else if (name) {
       item.component = getParentLayout();
     }
+    // 处理props传参
+    item.props = (route: RouteLocationNormalized) => {
+      const result: Recordable = {};
+      if (meta.queryToProps) {
+        Object.assign(result, route.query);
+      }
+      return result;
+    };
     children && asyncImportRoute(children);
   });
 }