diff --git a/src/components/SmartTable/index.ts b/src/components/SmartTable/index.ts
index 5b4adc37c..a9cbb6ab0 100644
--- a/src/components/SmartTable/index.ts
+++ b/src/components/SmartTable/index.ts
@@ -16,3 +16,4 @@ export * from './src/types/SmartTableColumnType';
export * from './src/types/SmartTableAuthType';
export * from './src/types/SmartTableToolbarConfigType';
export * from './src/utils/TableCommon';
+export * from './src/hooks/useVxeTableSortable';
diff --git a/src/components/SmartTable/src/hooks/useVxeTableSortable.ts b/src/components/SmartTable/src/hooks/useVxeTableSortable.ts
new file mode 100644
index 000000000..4ffaa4ec7
--- /dev/null
+++ b/src/components/SmartTable/src/hooks/useVxeTableSortable.ts
@@ -0,0 +1,40 @@
+import { onMounted, onUnmounted } from 'vue';
+import type { Ref } from 'vue';
+
+import Sortable from 'sortablejs';
+
+/**
+ * vxe支持行拖动
+ * @param tableRef
+ * @param handle css
+ * @param tableData 表格数据
+ */
+export const useVxeTableSortable = (tableRef: Ref, handle: string, tableData: Ref) => {
+ let sortable: any = null;
+ const handleRowDrop = () => {
+ if (sortable !== null) {
+ sortable.destroy();
+ }
+ sortable = Sortable.create(
+ tableRef.value.$el.querySelector('.body--wrapper>.vxe-table--body tbody'),
+ {
+ handle: handle,
+ animation: 150,
+ ghostClass: 'blue-background-class',
+ onEnd: ({ newIndex, oldIndex }: any) => {
+ const currentRow = tableData.value.splice(oldIndex, 1)[0];
+ tableData.value.splice(newIndex, 0, currentRow);
+ },
+ },
+ );
+ };
+ onUnmounted(() => {
+ if (sortable !== null) {
+ sortable.destroy();
+ }
+ });
+ onMounted(handleRowDrop);
+ return {
+ handleRowDrop,
+ };
+};
diff --git a/src/modules/codeGenerator/components/template/TemplateGroup.vue b/src/modules/codeGenerator/components/template/TemplateGroup.vue
new file mode 100644
index 000000000..4b132b906
--- /dev/null
+++ b/src/modules/codeGenerator/components/template/TemplateGroup.vue
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/constants/Constants.ts b/src/modules/codeGenerator/constants/Constants.ts
new file mode 100644
index 000000000..c2e452762
--- /dev/null
+++ b/src/modules/codeGenerator/constants/Constants.ts
@@ -0,0 +1,8 @@
+export const extensionLanguageMap: { [index: string]: string } = {
+ 'text/x-java': 'java',
+ xml: 'xml',
+ javascript: 'js',
+ html: 'html',
+ 'text/x-vue': 'vue',
+ typescript: 'ts',
+};
diff --git a/src/modules/codeGenerator/constants/DatabaseConstants.ts b/src/modules/codeGenerator/constants/DatabaseConstants.ts
new file mode 100644
index 000000000..ffdee6651
--- /dev/null
+++ b/src/modules/codeGenerator/constants/DatabaseConstants.ts
@@ -0,0 +1,13 @@
+/**
+ * 模板类型
+ */
+export const TemplateType: any = {
+ TEMPLATE_CODE: {
+ value: 'TEMPLATE_CODE',
+ label: 'generator.views.template.label.templateType.templateCode',
+ },
+ TEMPLATE_DB_DICT: {
+ value: 'TEMPLATE_DB_DICT',
+ label: 'generator.views.template.label.templateType.templateDbDict',
+ },
+};
diff --git a/src/modules/codeGenerator/router/CodeBasicRouter.ts b/src/modules/codeGenerator/router/CodeBasicRouter.ts
new file mode 100644
index 000000000..43dedb7f7
--- /dev/null
+++ b/src/modules/codeGenerator/router/CodeBasicRouter.ts
@@ -0,0 +1,11 @@
+import { AppRouteRecordRaw } from '@/router/types';
+
+export const CREATE_CODE_ROUTER: AppRouteRecordRaw = {
+ path: '/codeCreateView',
+ name: 'CodeCreateView',
+ meta: {
+ title: '生成代码',
+ },
+ component: () => import('/@/modules/codeGenerator/views/codeCreate/CodeCreateView.vue'),
+ props: (route) => route.query,
+};
diff --git a/src/modules/codeGenerator/views/codeCreate/CodeCreateSupport.ts b/src/modules/codeGenerator/views/codeCreate/CodeCreateSupport.ts
new file mode 100644
index 000000000..b8105984d
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeCreate/CodeCreateSupport.ts
@@ -0,0 +1,11 @@
+/**
+ * 扩展名类型映射
+ */
+export const extensionLanguageMap: any = {
+ 'text/x-java': 'java',
+ xml: 'xml',
+ javascript: 'js',
+ html: 'html',
+ 'text/x-vue': 'vue',
+ typescript: 'ts',
+};
diff --git a/src/modules/codeGenerator/views/codeCreate/CodeCreateView.vue b/src/modules/codeGenerator/views/codeCreate/CodeCreateView.vue
new file mode 100644
index 000000000..232733d4e
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeCreate/CodeCreateView.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeCreate/CodeCreateViewOld.vue b/src/modules/codeGenerator/views/codeCreate/CodeCreateViewOld.vue
new file mode 100644
index 000000000..bf065686a
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeCreate/CodeCreateViewOld.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeDesign/CodeDesignPage.api.ts b/src/modules/codeGenerator/views/codeDesign/CodeDesignPage.api.ts
new file mode 100644
index 000000000..225197590
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/CodeDesignPage.api.ts
@@ -0,0 +1,30 @@
+import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
+
+enum Api {
+ queryDbTable = 'db/connection/queryDbTable',
+ getConfigById = 'db/code/main/getConfigById',
+ saveConfig = 'db/code/main/save',
+}
+
+/**
+ * 查询数据库信息
+ * @param connectionId
+ * @param tableName
+ */
+export const queryDbTableApi = (connectionId: number, tableName: number) =>
+ defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: Api.queryDbTable,
+ data: { dbConnectionId: connectionId, tableName },
+ });
+
+export const getConfigByIdApi = (configId: number) =>
+ defHttp.post({ service: ApiServiceEnum.SMART_CODE, url: Api.getConfigById, data: configId });
+
+export const saveConfigApi = (model: Recordable) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: Api.saveConfig,
+ data: model,
+ });
+};
diff --git a/src/modules/codeGenerator/views/codeDesign/CodeDesignPage.config.ts b/src/modules/codeGenerator/views/codeDesign/CodeDesignPage.config.ts
new file mode 100644
index 000000000..2636b603f
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/CodeDesignPage.config.ts
@@ -0,0 +1,330 @@
+import type { FormSchema } from '@/components/Form';
+
+type ButtonType =
+ | 'SEARCH'
+ | 'RESET'
+ | 'ADD'
+ | 'EDIT'
+ | 'DELETE'
+ | 'EXCEL_IMPORT'
+ | 'EXCEL_EXPORT'
+ | 'COLUMN_SETTING'
+ | 'ZOOM'
+ | 'REFRESH'
+ | 'SHOW_SEARCH'
+ | 'PRINT';
+
+interface Button {
+ key: ButtonType;
+ value: string;
+}
+
+const tableTypeList = [
+ {
+ label: 'generator.views.code.title.tableType.single',
+ value: '10',
+ },
+ {
+ label: 'generator.views.code.title.tableType.main',
+ value: '20',
+ },
+ {
+ label: 'generator.views.code.title.tableType.addendum',
+ value: '30',
+ },
+];
+
+const yesNoList = [
+ {
+ label: 'Yes',
+ value: true,
+ },
+ {
+ label: 'No',
+ value: false,
+ },
+];
+
+export const formSchemas = (t: Function): FormSchema[] => {
+ return [
+ {
+ label: '',
+ field: 'systemId',
+ component: 'Input',
+ show: false,
+ },
+ {
+ label: t('generator.views.code.table.connectionName'),
+ field: 'connectionId',
+ slot: 'addEditForm-connectionId',
+ required: true,
+ },
+ {
+ label: t('generator.views.code.table.tableName'),
+ field: 'tableName',
+ component: 'Input',
+ required: true,
+ },
+ {
+ label: t('generator.views.code.table.configName'),
+ field: 'configName',
+ component: 'Input',
+ required: true,
+ },
+ {
+ label: t('generator.views.code.table.type'),
+ field: 'type',
+ component: 'Select',
+ defaultValue: '10',
+ componentProps: {
+ options: tableTypeList.map((item) => ({ label: t(item.label), value: item.value })),
+ },
+ },
+ // ------------ 第二行 ---------------------
+ {
+ label: t('generator.views.code.title.showCheckBox'),
+ field: 'showCheckbox',
+ component: 'RadioGroup',
+ defaultValue: true,
+ componentProps: {
+ options: yesNoList,
+ },
+ },
+ {
+ label: t('generator.views.code.title.isPage'),
+ field: 'page',
+ component: 'RadioGroup',
+ defaultValue: true,
+ componentProps: {
+ options: yesNoList,
+ },
+ },
+ {
+ label: t('generator.views.code.title.invented'),
+ field: 'invented',
+ component: 'RadioGroup',
+ defaultValue: false,
+ componentProps: {
+ options: yesNoList,
+ },
+ },
+ {
+ label: t('generator.views.code.title.columnSort'),
+ field: 'columnSort',
+ component: 'RadioGroup',
+ defaultValue: false,
+ componentProps: {
+ options: yesNoList,
+ },
+ },
+ // ------------ 第三行 ---------------------
+ {
+ label: t('generator.views.code.title.leftButton'),
+ field: 'leftButtonList',
+ component: 'Select',
+ defaultValue: ['ADD', 'DELETE'],
+ componentProps: {
+ mode: 'multiple',
+ options: letButtonList.map((item) => ({
+ label: item.value,
+ value: item.key,
+ })),
+ },
+ },
+ {
+ label: t('generator.views.code.title.rightButton'),
+ field: 'rightButtonList',
+ component: 'Select',
+ defaultValue: ['ZOOM', 'REFRESH', 'SHOW_SEARCH', 'COLUMN_SETTING'],
+ componentProps: {
+ mode: 'multiple',
+ options: rightButtonList.map((item) => ({
+ label: item.value,
+ value: item.key,
+ })),
+ },
+ },
+ {
+ label: t('generator.views.code.title.rowButtonType.title'),
+ field: 'rowButtonType',
+ component: 'Select',
+ defaultValue: 'NONE',
+ componentProps: {
+ options: rowButtonTypeList(t),
+ },
+ },
+ {
+ label: t('generator.views.code.title.rowButtonList'),
+ field: 'rowButtonList',
+ component: 'Select',
+ componentProps: {
+ mode: 'multiple',
+ options: rowButtonList.map((item) => ({
+ label: item.value,
+ value: item.key,
+ })),
+ },
+ },
+ // ------------ 第四行 ---------------------
+ {
+ label: t('generator.views.code.title.formColNum'),
+ field: 'formColNum',
+ component: 'Select',
+ defaultValue: 1,
+ componentProps: {
+ options: columnNumList(t, false),
+ },
+ },
+ {
+ label: t('generator.views.code.title.searchColNum'),
+ field: 'searchColNum',
+ component: 'Select',
+ defaultValue: 0,
+ componentProps: {
+ options: columnNumList(t),
+ },
+ },
+ {
+ label: t('common.table.remark'),
+ field: 'remark',
+ component: 'Input',
+ },
+ {
+ label: t('generator.views.code.title.i18nPrefix'),
+ field: 'i18nPrefix',
+ component: 'Input',
+ },
+ // ------------ 第五行 ---------------------
+ {
+ label: t('generator.views.code.title.relateTable'),
+ field: 'addendumTableList',
+ defaultValue: [],
+ slot: 'addEditForm-RelateTable',
+ },
+ {
+ label: '',
+ field: 'id',
+ slot: 'addEditForm-syncTable',
+ },
+ ];
+};
+
+/**
+ * 左侧按钮列表
+ */
+const letButtonList: Button[] = [
+ {
+ key: 'SEARCH',
+ value: '搜索',
+ },
+ {
+ key: 'RESET',
+ value: '重置',
+ },
+ {
+ key: 'ADD',
+ value: '添加',
+ },
+ {
+ key: 'EDIT',
+ value: '修改',
+ },
+ {
+ key: 'DELETE',
+ value: '删除',
+ },
+];
+
+const rightButtonList: Button[] = [
+ {
+ key: 'EXCEL_IMPORT',
+ value: 'Excel导入',
+ },
+ {
+ key: 'EXCEL_EXPORT',
+ value: 'Excel导出',
+ },
+ {
+ key: 'COLUMN_SETTING',
+ value: '列配置',
+ },
+ {
+ key: 'ZOOM',
+ value: '放大缩小',
+ },
+ {
+ key: 'REFRESH',
+ value: '刷新',
+ },
+ {
+ key: 'SHOW_SEARCH',
+ value: '显示搜索',
+ },
+ {
+ key: 'PRINT',
+ value: '打印',
+ },
+];
+
+/**
+ * 行按钮
+ */
+const rowButtonList = [
+ {
+ key: 'EDIT',
+ value: '修改',
+ },
+ {
+ key: 'DELETE',
+ value: '删除',
+ },
+];
+
+const columnNumList = (t: Function, hasZeroColumn = true) => {
+ const column = [
+ {
+ value: 1,
+ label: t('generator.views.code.title.colNum.one'),
+ },
+ {
+ value: 2,
+ label: t('generator.views.code.title.colNum.two'),
+ },
+ {
+ value: 3,
+ label: t('generator.views.code.title.colNum.three'),
+ },
+ {
+ value: 4,
+ label: t('generator.views.code.title.colNum.four'),
+ },
+ ];
+ if (hasZeroColumn) {
+ return [
+ {
+ value: 0,
+ label: t('generator.views.design.title.colNum.zero'),
+ },
+ ].concat(column);
+ }
+ return column;
+};
+
+const rowButtonTypeList = (t: Function) => [
+ {
+ label: t('generator.views.code.title.rowButtonType.none'),
+ value: 'NONE',
+ },
+ {
+ label: t('generator.views.code.title.rowButtonType.single'),
+ value: 'SINGLE',
+ },
+ {
+ label: t('generator.views.code.title.rowButtonType.more'),
+ value: 'MORE',
+ },
+ {
+ label: t('generator.views.code.title.rowButtonType.text'),
+ value: 'TEXT',
+ },
+];
diff --git a/src/modules/codeGenerator/views/codeDesign/CodeDesignPage.vue b/src/modules/codeGenerator/views/codeDesign/CodeDesignPage.vue
new file mode 100644
index 000000000..536214e02
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/CodeDesignPage.vue
@@ -0,0 +1,250 @@
+
+
+
+
+
+
+
+ {{ $t('common.button.reload') }}
+
+
+ {{ $t('common.button.save') }}
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeDesign/CodeDesignPageHook.ts b/src/modules/codeGenerator/views/codeDesign/CodeDesignPageHook.ts
new file mode 100644
index 000000000..475dbef60
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/CodeDesignPageHook.ts
@@ -0,0 +1,142 @@
+import { computed, createVNode, Ref, ref, unref } from 'vue';
+
+import { queryDbTableApi, saveConfigApi } from './CodeDesignPage.api';
+import { message, Modal } from 'ant-design-vue';
+import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
+
+/**
+ * 加载数据库数据
+ */
+export const useLoadDbData = (validate: Function) => {
+ // 数据库数据加载状态
+ const dbDataLoading = ref(false);
+ const dbDataRef = ref({});
+ const isSyncRef = ref(false);
+
+ /**
+ * 表格table计算属性
+ */
+ const computedTableData = computed(() => {
+ const dbData = unref(dbDataRef);
+ if (!dbData.tableName) {
+ return [];
+ }
+ const primaryKeyList = dbData.primaryKeyList || [];
+ const baseColumnList = dbData.baseColumnList || [];
+ return [...primaryKeyList, ...baseColumnList];
+ });
+
+ const handleSyncTableData = async () => {
+ const { connectionId, tableName } = await validate();
+ try {
+ dbDataLoading.value = true;
+ dbDataRef.value = await queryDbTableApi(connectionId, tableName);
+ isSyncRef.value = true;
+ } finally {
+ dbDataLoading.value = false;
+ }
+ };
+
+ return {
+ dbDataLoading,
+ dbDataRef,
+ computedTableData,
+ isSyncRef,
+ handleSyncTableData,
+ };
+};
+
+/**
+ * 保存操作hook
+ */
+export const useSaveConfig = (
+ t: Function,
+ isSync: Ref,
+ validate: Function,
+ dbDataRef: Ref,
+ afterSave?: Function,
+) => {
+ const pageTableSettingRef = ref();
+ const pageSearchSettingRef = ref();
+ const pageFormSettingRef = ref();
+
+ const saveLoading = ref(false);
+
+ const handleSave = () => {
+ if (!unref(isSync)) {
+ message.warn(t('generator.views.code.validate.syncTable'));
+ return false;
+ }
+ if (!unref(pageTableSettingRef)) {
+ message.warn(t('generator.views.code.validate.tableSetting'));
+ return false;
+ }
+ if (!unref(pageFormSettingRef)) {
+ message.warn(t('generator.views.code.validate.formSetting'));
+ return false;
+ }
+ // 搜索配置实体
+ if (!unref(pageSearchSettingRef)) {
+ message.warn(t('generator.views.code.validate.searchSetting'));
+ return false;
+ }
+ // 验证必填字段是否设置表单
+ const pageFormSettingData = unref(pageFormSettingRef).getData() as Array;
+ const nonNullField: Array = [];
+ pageFormSettingData.forEach((item) => {
+ if (item.nullable === 0 && (item.visible === false || item.used === false)) {
+ nonNullField.push(item.columnName);
+ }
+ });
+ if (nonNullField.length > 0) {
+ Modal.confirm({
+ title: t('common.notice.confirmSave'),
+ icon: createVNode(ExclamationCircleOutlined),
+ content: t('generator.views.code.message.saveConfirmContent', nonNullField.join(',')),
+ onCancel() {
+ return false;
+ },
+ onOk() {
+ doSave();
+ },
+ });
+ } else {
+ doSave();
+ }
+ };
+
+ const doSave = async () => {
+ const formModel = await validate();
+ const dbData = unref(dbDataRef);
+ const saveData = {
+ ...formModel,
+ codePageConfigList: unref(pageTableSettingRef).getData(),
+ codeFormConfigList: unref(pageFormSettingRef).getData(),
+ codeSearchConfigList: unref(pageSearchSettingRef).getData(),
+ className: dbData.className,
+ remarks: dbData.remarks,
+ };
+ try {
+ saveLoading.value = true;
+ const configId = await saveConfigApi(saveData);
+ afterSave && afterSave(configId);
+ } catch (e: any) {
+ if (e.code === 400) {
+ e.data.forEach((item: string) => {
+ message.error(item);
+ });
+ }
+ return false;
+ } finally {
+ saveLoading.value = false;
+ }
+ };
+
+ return {
+ handleSave,
+ pageTableSettingRef,
+ pageSearchSettingRef,
+ pageFormSettingRef,
+ saveLoading,
+ };
+};
diff --git a/src/modules/codeGenerator/views/codeDesign/componenets/DatabaseSelect/DatabaseSelect.vue b/src/modules/codeGenerator/views/codeDesign/componenets/DatabaseSelect/DatabaseSelect.vue
new file mode 100644
index 000000000..0f946459c
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/componenets/DatabaseSelect/DatabaseSelect.vue
@@ -0,0 +1,54 @@
+
+
+
+ {{ item.value }}
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeDesign/componenets/PageAddendumTableChoseModal.vue b/src/modules/codeGenerator/views/codeDesign/componenets/PageAddendumTableChoseModal.vue
new file mode 100644
index 000000000..753209a95
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/componenets/PageAddendumTableChoseModal.vue
@@ -0,0 +1,210 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeDesign/componenets/PageFromSetting/FormRuleSetModal.vue b/src/modules/codeGenerator/views/codeDesign/componenets/PageFromSetting/FormRuleSetModal.vue
new file mode 100644
index 000000000..5de902a4d
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/componenets/PageFromSetting/FormRuleSetModal.vue
@@ -0,0 +1,222 @@
+
+
+
+
+
+ handleDeleteRow(row)">删除
+
+
+
+ 添加一行
+
+
+
+
+
+
+ 开启后,校验参数自动生成,配置的校验内容无效
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeDesign/componenets/PageFromSetting/PageFormSetting.vue b/src/modules/codeGenerator/views/codeDesign/componenets/PageFromSetting/PageFormSetting.vue
new file mode 100644
index 000000000..bb0006ec8
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/componenets/PageFromSetting/PageFormSetting.vue
@@ -0,0 +1,362 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t(item.value) }}
+
+
+
+
+ 选择表格
+
+ handleShowChoseSelectTable(row)"
+ />
+
+
+
+
+ openRuleSetModal(true, row)">
+ 设置规则
+
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeDesign/componenets/PageSearchSetting/PageSearchSetting.vue b/src/modules/codeGenerator/views/codeDesign/componenets/PageSearchSetting/PageSearchSetting.vue
new file mode 100644
index 000000000..5f4c8326a
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/componenets/PageSearchSetting/PageSearchSetting.vue
@@ -0,0 +1,380 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t(item.value) }}
+
+
+
+
+ 选择表格
+
+ handleShowChoseSelectTable(row)"
+ />
+
+
+
+
+
+ {{ item.value }}
+
+
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeDesign/componenets/PageSettingSupport.ts b/src/modules/codeGenerator/views/codeDesign/componenets/PageSettingSupport.ts
new file mode 100644
index 000000000..503ac00bc
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/componenets/PageSettingSupport.ts
@@ -0,0 +1,174 @@
+import { ref, watch } from 'vue';
+import type { Ref } from 'vue';
+import { useModal } from '@/components/Modal';
+
+/**
+ * 空间列表
+ */
+export const controlList = [
+ {
+ key: 'INPUT',
+ value: 'generator.views.code.title.controlList.input',
+ },
+ {
+ key: 'TEXTAREA',
+ value: 'generator.views.code.title.controlList.textarea',
+ },
+ {
+ key: 'NUMBER',
+ value: 'generator.views.code.title.controlList.number',
+ },
+ {
+ key: 'PASSWORD',
+ value: 'generator.views.code.title.controlList.password',
+ },
+ {
+ key: 'SELECT',
+ value: 'generator.views.code.title.controlList.select',
+ },
+ {
+ key: 'TRANSFER',
+ value: 'generator.views.code.title.controlList.transfer',
+ },
+ {
+ key: 'SELECT_TABLE',
+ value: 'generator.views.code.title.controlList.selectTable',
+ },
+ {
+ key: 'RADIO',
+ value: 'generator.views.code.title.controlList.radio',
+ },
+ {
+ key: 'CHECKBOX',
+ value: 'generator.views.code.title.controlList.checkbox',
+ },
+ {
+ key: 'SWITCH_TYPE',
+ value: 'generator.views.code.title.controlList.switch_type',
+ },
+ {
+ key: 'DATE',
+ value: 'generator.views.code.title.controlList.date',
+ },
+ {
+ key: 'TIME',
+ value: 'generator.views.code.title.controlList.time',
+ },
+ {
+ key: 'DATETIME',
+ value: 'generator.views.code.title.controlList.datetime',
+ },
+ {
+ key: 'FILE',
+ value: 'generator.views.code.title.controlList.file',
+ },
+ {
+ key: 'DATA_DICT',
+ value: 'generator.views.design.title.controlList.dataDict',
+ },
+ {
+ key: 'CATEGORY_DICT',
+ value: 'generator.views.design.title.controlList.categoryDict',
+ },
+];
+
+/**
+ * rule列表
+ */
+const ruleList = [
+ {
+ value: 'NOT_EMPTY',
+ label: 'generator.views.code.title.ruleList.notEmpty',
+ },
+ {
+ value: 'PHONE',
+ label: 'generator.views.code.title.ruleList.PHONE',
+ },
+ {
+ value: 'EMAIL',
+ label: 'generator.views.code.title.ruleList.EMAIL',
+ },
+ {
+ value: 'NUMBER',
+ label: 'generator.views.code.title.ruleList.NUMBER',
+ },
+ {
+ value: 'REGEXP',
+ label: 'generator.views.code.title.ruleList.REGEXP',
+ },
+];
+
+export const getRuleList = (t: Function): Recordable[] => {
+ return ruleList.map((item) => {
+ return {
+ ...item,
+ label: t(item.label),
+ };
+ });
+};
+
+/**
+ * 查询标识列表
+ */
+export const searchSymbolList = [
+ '=',
+ 'like',
+ '>',
+ '>=',
+ '<',
+ '<=',
+ 'in',
+ 'notIn',
+ 'notLike',
+ 'likeLeft',
+ 'likeRight',
+];
+
+/**
+ * table header checkbox
+ * @param tableData
+ * @param field
+ * @param defaultValue
+ */
+export const vueTableHeaderCheckboxSupport = (
+ tableData: Ref,
+ field: string,
+ defaultValue = true,
+) => {
+ const checked = ref(defaultValue);
+ watch(checked, () => {
+ tableData.value.forEach((item: any) => {
+ item[field] = checked.value;
+ });
+ });
+ return {
+ checked,
+ };
+};
+
+/**
+ * 下拉表格支持
+ */
+export const vueChoseSelectTableSupport = (currentRow: Ref) => {
+ const [registerSelectTableModal, { openModal: openSelectTableModal }] = useModal();
+ /**
+ * 显示列选择
+ * @param row
+ */
+ const handleShowChoseSelectTable = (row: any) => {
+ currentRow.value = row;
+ openSelectTableModal(true, {});
+ };
+ /**
+ * 选择表格后
+ * @param tableList
+ */
+ const handleChoseTable = (tableList: Array) => {
+ currentRow.value.selectTableList = tableList;
+ };
+ return {
+ registerSelectTableModal,
+ handleShowChoseSelectTable,
+ handleChoseTable,
+ };
+};
diff --git a/src/modules/codeGenerator/views/codeDesign/componenets/PageTableSetting/PageTableSetting.vue b/src/modules/codeGenerator/views/codeDesign/componenets/PageTableSetting/PageTableSetting.vue
new file mode 100644
index 000000000..655a15dc0
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/componenets/PageTableSetting/PageTableSetting.vue
@@ -0,0 +1,331 @@
+
+
+
+
+
+
+
+
+ left
+ right
+
+
+
+
+
+
+
+
+
+
+
+
+
+ left
+ center
+ right
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+
+
+
+
+ {{ $t(column.title.replace('{', '').replace('}', '')) }}
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeDesign/componenets/TableFieldTable/TableFieldTable.vue b/src/modules/codeGenerator/views/codeDesign/componenets/TableFieldTable/TableFieldTable.vue
new file mode 100644
index 000000000..25b603d56
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/componenets/TableFieldTable/TableFieldTable.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeDesign/lang/en_US.ts b/src/modules/codeGenerator/views/codeDesign/lang/en_US.ts
new file mode 100644
index 000000000..350891bf6
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/lang/en_US.ts
@@ -0,0 +1,20 @@
+export default {
+ trans: true,
+ key: 'generator.views.design',
+ data: {
+ title: {
+ controlList: {
+ dataDict: 'Data dict',
+ categoryDict: 'Category dict',
+ },
+ colNum: {
+ zero: 'inline',
+ },
+ },
+ formSetting: {
+ title: {
+ tableName: 'Model class',
+ },
+ },
+ },
+};
diff --git a/src/modules/codeGenerator/views/codeDesign/lang/zh_CN.ts b/src/modules/codeGenerator/views/codeDesign/lang/zh_CN.ts
new file mode 100644
index 000000000..0c44b2dac
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeDesign/lang/zh_CN.ts
@@ -0,0 +1,20 @@
+export default {
+ trans: true,
+ key: 'generator.views.design',
+ data: {
+ title: {
+ controlList: {
+ dataDict: '数据字典',
+ categoryDict: '分类字典',
+ },
+ colNum: {
+ zero: '单行',
+ },
+ },
+ formSetting: {
+ title: {
+ tableName: '实体类名',
+ },
+ },
+ },
+};
diff --git a/src/modules/codeGenerator/views/codeList/CodeListView.api.ts b/src/modules/codeGenerator/views/codeList/CodeListView.api.ts
new file mode 100644
index 000000000..b6515167f
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeList/CodeListView.api.ts
@@ -0,0 +1,16 @@
+import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
+
+enum Api {
+ listBySystem = 'db/code/main/listBySystem',
+ delete = 'db/code/main/batchDeleteById',
+}
+
+export const listBySystemApi = (parameter) =>
+ defHttp.post({ service: ApiServiceEnum.SMART_CODE, url: Api.listBySystem, data: parameter });
+
+export const deleteApi = (data) =>
+ defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: Api.delete,
+ data: data.map((item: any) => item.id),
+ });
diff --git a/src/modules/codeGenerator/views/codeList/CodeListView.config.tsx b/src/modules/codeGenerator/views/codeList/CodeListView.config.tsx
new file mode 100644
index 000000000..a19278e11
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeList/CodeListView.config.tsx
@@ -0,0 +1,136 @@
+import type { SmartColumn, SmartSearchFormSchema } from '@/components/SmartTable';
+
+const tableTypeList = [
+ {
+ label: 'generator.views.code.title.tableType.single',
+ value: '10',
+ color: 'green',
+ },
+ {
+ label: 'generator.views.code.title.tableType.main',
+ value: '20',
+ color: 'blue',
+ },
+ {
+ label: 'generator.views.code.title.tableType.addendum',
+ value: '30',
+ color: 'purple',
+ },
+];
+
+export const tableColumns = (t: Function): SmartColumn[] => {
+ return [
+ {
+ type: 'checkbox',
+ width: 60,
+ fixed: 'left',
+ },
+ {
+ title: '{generator.views.code.table.connectionName}',
+ field: 'connectionName',
+ width: 160,
+ fixed: 'left',
+ },
+ {
+ title: '{generator.views.code.table.configName}',
+ field: 'configName',
+ width: 160,
+ fixed: 'left',
+ },
+ {
+ title: '{generator.views.code.table.tableName}',
+ field: 'tableName',
+ width: 160,
+ fixed: 'left',
+ },
+ {
+ title: '{generator.views.code.table.type}',
+ field: 'type',
+ width: 120,
+ slots: {
+ default: ({ row }) => {
+ const value = row.type;
+ if (value) {
+ const filterList = tableTypeList.filter((item) => item.value === value);
+ if (filterList.length > 0) {
+ const data = filterList[0];
+ return {t(data.label)};
+ }
+ }
+ return '';
+ },
+ },
+ },
+ {
+ title: '{generator.views.code.table.remarks}',
+ field: 'remarks',
+ minWidth: 200,
+ },
+ {
+ title: '{common.table.remark}',
+ field: 'remark',
+ minWidth: 200,
+ },
+ {
+ title: '{common.table.createTime}',
+ field: 'createTime',
+ width: 165,
+ sortable: true,
+ },
+ {
+ title: '{common.table.createUser}',
+ field: 'createBy',
+ width: 120,
+ },
+ {
+ title: '{common.table.updateTime}',
+ field: 'updateTime',
+ width: 165,
+ sortable: true,
+ },
+ {
+ title: '{common.table.updateUser}',
+ field: 'updateBy',
+ width: 120,
+ },
+ {
+ title: '{common.table.operation}',
+ field: 'operation',
+ width: 140,
+ fixed: 'right',
+ slots: {
+ default: 'table-operation',
+ },
+ },
+ ];
+};
+
+export const searchFormColumns = (t: Function): SmartSearchFormSchema[] => {
+ return [
+ {
+ field: 'tableName',
+ label: '',
+ component: 'Input',
+ componentProps: {
+ placeholder: t('generator.views.code.table.tableName'),
+ },
+ },
+ {
+ field: 'type',
+ label: '',
+ component: 'Select',
+ componentProps: {
+ style: {
+ width: '100px',
+ },
+ placeholder: t('generator.views.code.table.type'),
+ options: tableTypeList.map((item) => {
+ return {
+ ...item,
+ label: t(item.label),
+ };
+ }),
+ },
+ },
+ ];
+};
diff --git a/src/modules/codeGenerator/views/codeList/CodeListView.vue b/src/modules/codeGenerator/views/codeList/CodeListView.vue
new file mode 100644
index 000000000..c1f0d96de
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeList/CodeListView.vue
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeList/components/CodeCreateForm.vue b/src/modules/codeGenerator/views/codeList/components/CodeCreateForm.vue
new file mode 100644
index 000000000..17ac96ce3
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeList/components/CodeCreateForm.vue
@@ -0,0 +1,187 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeList/components/CodeCreateModal.vue b/src/modules/codeGenerator/views/codeList/components/CodeCreateModal.vue
new file mode 100644
index 000000000..092a6f619
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeList/components/CodeCreateModal.vue
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeList/components/CodeListAddEditModal.vue b/src/modules/codeGenerator/views/codeList/components/CodeListAddEditModal.vue
new file mode 100644
index 000000000..6edd88bc6
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeList/components/CodeListAddEditModal.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeList/components/TemplateSelectTable.vue b/src/modules/codeGenerator/views/codeList/components/TemplateSelectTable.vue
new file mode 100644
index 000000000..9ec62684c
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeList/components/TemplateSelectTable.vue
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/codeList/hooks/useLoadDbData.ts b/src/modules/codeGenerator/views/codeList/hooks/useLoadDbData.ts
new file mode 100644
index 000000000..82672dbd7
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeList/hooks/useLoadDbData.ts
@@ -0,0 +1,55 @@
+import { computed, ref } from 'vue';
+import { isEmpty } from '@/utils/is';
+import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
+
+export const useLoadDbData = ({ validateAddEdit }) => {
+ // 数据库数据加载状态
+ const dbDataLoading = ref(false);
+ const dbData = ref({});
+
+ /**
+ * 加载数据库数据
+ */
+ const loadDbData = async () => {
+ const { connectionId, tableName } = await validateAddEdit();
+ if (!isEmpty(connectionId) && !isEmpty(tableName)) {
+ dbDataLoading.value = true;
+ try {
+ dbData.value = await defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: 'db/connection/queryDbTable',
+ data: {
+ dbConnectionId: connectionId,
+ tableName: tableName,
+ },
+ });
+ } finally {
+ dbDataLoading.value = false;
+ }
+ }
+ };
+ /**
+ * 表格table计算属性
+ */
+ const computedTableData = computed(() => {
+ if (!dbData.value.tableName) {
+ return [];
+ }
+ const primaryKeyList = dbData.value.primaryKeyList || [];
+ const baseColumnList = dbData.value.baseColumnList || [];
+ return [...primaryKeyList, ...baseColumnList];
+ });
+ /**
+ * 同步表
+ */
+ const handleSyncTableData = () => {
+ loadDbData();
+ };
+ return {
+ dbData,
+ dbDataLoading,
+ computedTableData,
+ handleSyncTableData,
+ loadDbData,
+ };
+};
diff --git a/src/modules/codeGenerator/views/codeList/lang/en_US.ts b/src/modules/codeGenerator/views/codeList/lang/en_US.ts
new file mode 100644
index 000000000..0a0e557e7
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeList/lang/en_US.ts
@@ -0,0 +1,166 @@
+export default {
+ generator: {
+ views: {
+ code: {
+ table: {
+ connectionName: 'Connection name',
+ configName: 'Config name',
+ tableName: 'Table name',
+ type: 'Type',
+ remarks: 'Table remark',
+ },
+ title: {
+ dbMessage: 'DB information',
+ tableSetting: 'Table setting',
+ formSetting: 'Form setting',
+ searchSetting: 'Search setting',
+ design: 'Design',
+ showCheckBox: 'Show check box',
+ isPage: 'Pagination',
+ invented: 'Virtual scrolling',
+ columnSort: 'Order adjustable',
+ leftButton: 'Left button',
+ rightButton: 'Right button',
+ rowButtonType: {
+ title: 'Row button type',
+ none: 'none',
+ single: 'unified',
+ more: 'more',
+ text: 'text',
+ },
+ rowButtonList: 'Row button',
+ formColNum: 'Form col num',
+ searchColNum: 'Search col num',
+ relateTable: 'Relate addendum',
+ tableType: {
+ single: 'single',
+ main: 'main',
+ addendum: 'addendum',
+ },
+ colNum: {
+ one: 'One column',
+ two: 'Two column',
+ three: 'Three column',
+ four: 'Four column',
+ },
+ controlList: {
+ input: 'INPUT',
+ textarea: 'TEXTAREA',
+ number: 'NUMBER',
+ password: 'PASSWORD',
+ select: 'SELECT',
+ transfer: 'TRANSFER',
+ selectTable: 'SELECT_TABLE',
+ radio: 'RADIO',
+ checkbox: 'CHECKBOX',
+ switch_type: 'SWITCH',
+ date: 'DATE',
+ time: 'TIME',
+ datetime: 'DATETIME',
+ file: 'FILE',
+ },
+ ruleList: {
+ notEmpty: 'NOT_EMPTY',
+ PHONE: 'PHONE',
+ EMAIL: 'EMAIL',
+ NUMBER: 'NUMBER',
+ REGEXP: 'REGEXP',
+ },
+ i18nPrefix: 'I18n prefix',
+ },
+ button: {
+ createCode: 'Generate code',
+ syncTableData: 'Sync table information',
+ },
+ validate: {
+ connectionName: 'Please select a database connection',
+ tableName: 'Please enter a table name',
+ configName: 'Please enter the configuration name',
+ syncTable: 'Please synchronize table information first',
+ tableSetting: 'Please configure the table',
+ formSetting: 'Please configure the form',
+ searchSetting: 'Please configure the search',
+ i18nPrefix: 'Please enter the i18n prefix',
+ },
+ message: {
+ saveConfirmContent: 'Non empty field: [{0}] has no form set',
+ noSelectSystem: 'Please select system',
+ },
+ },
+ codeCreateForm: {
+ title: {
+ description: 'Function description',
+ tableName: 'Table name',
+ className: 'Model class name',
+ packages: 'packages',
+ extPackages: 'ext packages',
+ controllerBasePath: 'controller path',
+ choseAddendum: 'Select addendum',
+ customConfig: 'Custom config',
+ },
+ message: {
+ choseTemplate: 'Please select a template',
+ customConfig: 'Please enter json',
+ },
+ validate: {
+ packages: 'Please enter package',
+ className: 'Please enter model class name',
+ controllerBasePath: 'Path cannot be empty',
+ },
+ },
+ tableField: {
+ title: {
+ columnName: 'Column name',
+ typeName: 'Column type',
+ columnSize: 'Column size',
+ decimalDigits: 'Decimal digits',
+ columnDef: 'Default value',
+ nullable: 'Nullable',
+ remarks: 'Table remark',
+ primaryKey: 'Primary key',
+ indexed: 'Indexed',
+ },
+ },
+ tableSetting: {
+ title: {
+ title: 'Title',
+ sortable: 'Sortable',
+ fixed: 'Fixed',
+ width: 'Width',
+ align: 'Align',
+ resizable: 'Resizable',
+ visible: 'Render',
+ hidden: 'Hidden',
+ editable: 'Editable',
+ format: 'Format',
+ },
+ },
+ formSetting: {
+ title: {
+ controlType: 'Control type',
+ readonly: 'Readonly',
+ used: 'Transfer background',
+ useTableSearch: 'Query DB',
+ keyColumnName: 'Key column',
+ valueColumnName: 'Value column',
+ tableWhere: 'Query criteria/Dict code',
+ rules: 'Rules',
+ },
+ },
+ searchSetting: {
+ title: {
+ searchSymbol: 'Search identity',
+ },
+ },
+ addendumTable: {
+ title: {
+ relatedColumn: 'Associated field',
+ },
+ validate: {
+ relatedColumn: 'Please select an associated field',
+ relatedColumnWithConfig: 'Please set the associated field, configuration: {0}',
+ },
+ },
+ },
+ },
+};
diff --git a/src/modules/codeGenerator/views/codeList/lang/zh_CN.ts b/src/modules/codeGenerator/views/codeList/lang/zh_CN.ts
new file mode 100644
index 000000000..63333bde5
--- /dev/null
+++ b/src/modules/codeGenerator/views/codeList/lang/zh_CN.ts
@@ -0,0 +1,167 @@
+export default {
+ generator: {
+ views: {
+ code: {
+ table: {
+ connectionName: '连接名称',
+ configName: '配置名称',
+ tableName: '表名',
+ type: '类型',
+ remarks: '表备注',
+ },
+ title: {
+ dbMessage: '数据库信息',
+ tableSetting: '表格配置',
+ formSetting: '表单配置',
+ searchSetting: '查询配置',
+ design: '设计',
+ showCheckBox: '显示复选框',
+ isPage: '是否分页',
+ invented: '虚拟滚动',
+ columnSort: '列顺序可调',
+ leftButton: '左侧按钮',
+ rightButton: '右侧按钮',
+ rowButtonType: {
+ title: '行按钮类型',
+ none: '无',
+ single: '统一',
+ more: '多个',
+ text: '文本',
+ },
+ rowButtonList: '行操作按钮',
+ formColNum: '表单列数',
+ searchColNum: '搜索列数',
+ relateTable: '关联附表',
+ tableType: {
+ single: '单表',
+ main: '主表',
+ addendum: '附表',
+ },
+ colNum: {
+ one: '一列',
+ two: '两列',
+ three: '三列',
+ four: '四列',
+ },
+ controlList: {
+ input: '文本框',
+ textarea: '文本域',
+ number: '数字',
+ password: '密码',
+ select: '下拉框',
+ transfer: '穿梭框',
+ selectTable: '下拉表格',
+ radio: '单选框',
+ checkbox: '多选框',
+ switch_type: '开关',
+ date: '日期',
+ time: '时间',
+ datetime: '日期时间',
+ file: '文件',
+ },
+ ruleList: {
+ notEmpty: '非空',
+ PHONE: '手机号码',
+ EMAIL: '邮箱',
+ NUMBER: '数字',
+ REGEXP: '正则',
+ },
+ i18nPrefix: '国际化前缀',
+ },
+ button: {
+ createCode: '生成代码',
+ syncTableData: '同步表信息',
+ },
+ validate: {
+ connectionName: '请选择数据库连接',
+ tableName: '请输入表名',
+ configName: '请输入配置名',
+ syncTable: '请先同步表信息',
+ tableSetting: '请进行表格配置',
+ formSetting: '请进行表单配置',
+ searchSetting: '请进行搜索配置',
+ i18nPrefix: '请输入国际化前缀',
+ },
+ message: {
+ saveConfirmContent: '非空字段:【{0}】未设置form',
+ noSelectSystem: '请选择系统',
+ },
+ },
+ codeCreateForm: {
+ title: {
+ description: '功能描述',
+ tableName: '表名',
+ className: '实体类名',
+ packages: '包名',
+ extPackages: 'ext包名',
+ controllerBasePath: 'controller路径',
+ choseAddendum: '选择附表',
+ customConfig: '自定义配置',
+ templateList: '模板',
+ },
+ message: {
+ choseTemplate: '请选择模板',
+ customConfig: '请输入json',
+ },
+ validate: {
+ packages: '请输入包名',
+ className: '请输入实体类名',
+ controllerBasePath: '路径不能为空',
+ },
+ },
+ tableField: {
+ title: {
+ columnName: '字段名称',
+ typeName: '字段类型',
+ columnSize: '字段长度',
+ decimalDigits: '小数位数',
+ columnDef: '默认值',
+ nullable: '允许空值',
+ remarks: '表备注',
+ primaryKey: '主键',
+ indexed: '索引',
+ },
+ },
+ tableSetting: {
+ title: {
+ title: '标题',
+ sortable: '是否排序',
+ fixed: '列冻结',
+ width: '宽度',
+ align: '对齐方式',
+ resizable: '支持拖动',
+ visible: '是否渲染',
+ hidden: '是否隐藏',
+ editable: '是否可编辑',
+ format: '格式化',
+ },
+ },
+ formSetting: {
+ title: {
+ controlType: '控件类型',
+ readonly: '是否只读',
+ used: '是否传送后台',
+ useTableSearch: '查询数据库',
+ keyColumnName: 'key字段',
+ valueColumnName: 'value字段',
+ tableWhere: '查询条件/字典code',
+ rules: '验证规则',
+ },
+ },
+ searchSetting: {
+ title: {
+ searchSymbol: '搜索标识',
+ },
+ },
+ addendumTable: {
+ title: {
+ relatedColumn: '关联字段',
+ },
+ validate: {
+ relatedColumn: '请选择关联字段',
+ relatedColumnWithConfig: '请设置关联字段,配置:{0}',
+ },
+ },
+ },
+ },
+};
diff --git a/src/modules/codeGenerator/views/database/DatabaseListHooks.ts b/src/modules/codeGenerator/views/database/DatabaseListHooks.ts
new file mode 100644
index 000000000..2632e0031
--- /dev/null
+++ b/src/modules/codeGenerator/views/database/DatabaseListHooks.ts
@@ -0,0 +1,19 @@
+import { testConnectedApi } from './DatabaseListView.api';
+import { message, Modal } from 'ant-design-vue';
+
+export const handleTestConnected = async (row, t: Function, setLoading) => {
+ try {
+ setLoading(true);
+ const result = await testConnectedApi(row.id);
+ if (result.result === true) {
+ message.success(t('generator.views.database.message.connectSuccess'));
+ } else {
+ Modal.error({
+ title: t('generator.views.database.message.connectFail'),
+ content: result.message,
+ });
+ }
+ } finally {
+ setLoading(false);
+ }
+};
diff --git a/src/modules/codeGenerator/views/database/DatabaseListView.api.ts b/src/modules/codeGenerator/views/database/DatabaseListView.api.ts
new file mode 100644
index 000000000..ada3295b4
--- /dev/null
+++ b/src/modules/codeGenerator/views/database/DatabaseListView.api.ts
@@ -0,0 +1,70 @@
+import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
+
+enum api {
+ saveUpdate = 'db/connection/saveUpdate',
+ getById = 'db/connection/getById',
+ listBySystem = 'db/connection/listBySystem',
+ batchDeleteById = 'db/connection/batchDeleteById',
+ testConnected = 'db/connection/testConnection',
+ listTemplate = 'db/code/template/list',
+ createDict = '/public/db/createDic',
+}
+
+export const saveUpdateApi = (data: any) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: api.saveUpdate,
+ data,
+ });
+};
+
+export const getByIdApi = (id: number) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: api.getById,
+ data: id,
+ });
+};
+
+export const listApi = (data?: any) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: api.listBySystem,
+ data,
+ });
+};
+
+export const deleteApi = async (rows: any[]) => {
+ if (rows.length === 0) {
+ return;
+ }
+ await defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: api.batchDeleteById,
+ data: rows.map((item: any) => item.id),
+ });
+};
+
+export const testConnectedApi = (id: number) =>
+ defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: api.testConnected,
+ data: id,
+ });
+
+export const listTemplate = (templateType?: string) =>
+ defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: api.listTemplate,
+ data: {
+ parameter: {
+ 'templateType@=': templateType,
+ },
+ },
+ });
+
+export const getCreateDicUrl = ({ row, templateId, tempToken }) => {
+ return `${defHttp.getApiUrlByService(
+ ApiServiceEnum.SMART_CODE,
+ )}/public/db/createDic?connectionId=${row.id}&templateId=${templateId}&access-token=${tempToken}`;
+};
diff --git a/src/modules/codeGenerator/views/database/DatabaseListView.data.ts b/src/modules/codeGenerator/views/database/DatabaseListView.data.ts
new file mode 100644
index 000000000..957599c7d
--- /dev/null
+++ b/src/modules/codeGenerator/views/database/DatabaseListView.data.ts
@@ -0,0 +1,203 @@
+import type { FormSchema } from '@/components/Form';
+import type { SmartColumn, SmartSearchFormSchema } from '@/components/SmartTable';
+
+const dbTypeList = ['MYSQL', 'SQL_SERVER', 'ORACLE'];
+
+export const tableColumns: SmartColumn[] = [
+ {
+ type: 'checkbox',
+ width: 60,
+ align: 'center',
+ fixed: 'left',
+ },
+ {
+ title: '{generator.views.database.table.connectionName}',
+ field: 'connectionName',
+ width: 160,
+ fixed: 'left',
+ },
+ {
+ title: '{generator.views.database.table.databaseName}',
+ field: 'databaseName',
+ width: 160,
+ fixed: 'left',
+ },
+ {
+ title: '{generator.views.database.table.type}',
+ field: 'type',
+ width: 120,
+ },
+ {
+ title: '{generator.views.database.table.url}',
+ field: 'url',
+ minWidth: 200,
+ showOverflow: 'tooltip',
+ },
+ {
+ title: '{generator.views.database.table.username}',
+ field: 'username',
+ width: 120,
+ },
+ {
+ title: '{generator.views.database.table.tableSchema}',
+ field: 'tableSchema',
+ width: 120,
+ },
+ {
+ title: '{common.table.createTime}',
+ field: 'createTime',
+ width: 165,
+ sortable: true,
+ },
+ {
+ title: '{common.table.createUser}',
+ field: 'createBy',
+ width: 120,
+ },
+ {
+ title: '{common.table.updateTime}',
+ field: 'updateTime',
+ width: 165,
+ sortable: true,
+ },
+ {
+ title: '{common.table.updateUser}',
+ field: 'updateBy',
+ width: 120,
+ },
+ {
+ title: '{common.table.operation}',
+ field: 'operation',
+ width: 120,
+ fixed: 'right',
+ slots: {
+ default: 'table-operation',
+ },
+ },
+];
+
+export const addEditForm: (t: Function) => Array = (t: Function) => {
+ return [
+ {
+ field: 'id',
+ component: 'Input',
+ show: false,
+ },
+ {
+ field: 'systemId',
+ component: 'Input',
+ show: false,
+ },
+ {
+ label: t('generator.views.database.table.connectionName'),
+ field: 'connectionName',
+ component: 'Input',
+ componentProps: {
+ placeholder: t('generator.views.database.validate.connectionName'),
+ },
+ required: true,
+ },
+ {
+ label: t('generator.views.database.table.databaseName'),
+ field: 'databaseName',
+ component: 'Input',
+ componentProps: {
+ placeholder: t('generator.views.database.validate.databaseName'),
+ },
+ required: true,
+ },
+ {
+ label: t('generator.views.database.table.type'),
+ field: 'type',
+ component: 'Select',
+ componentProps: {
+ placeholder: t('generator.views.database.validate.type'),
+ options: dbTypeList.map((item) => {
+ return {
+ label: item,
+ value: item,
+ };
+ }),
+ },
+ rules: [
+ {
+ message: t('generator.views.database.validate.type'),
+ required: true,
+ trigger: 'change',
+ },
+ ],
+ },
+ {
+ label: t('generator.views.database.table.url'),
+ field: 'url',
+ component: 'Input',
+ componentProps: {
+ placeholder: t('generator.views.database.validate.url'),
+ },
+ required: true,
+ },
+ {
+ label: t('generator.views.database.table.username'),
+ field: 'username',
+ component: 'Input',
+ componentProps: {
+ placeholder: t('generator.views.database.validate.username'),
+ },
+ required: true,
+ },
+ {
+ label: t('generator.views.database.table.password'),
+ field: 'password',
+ component: 'InputPassword',
+ componentProps: {
+ placeholder: t('generator.views.database.validate.password'),
+ },
+ required: true,
+ },
+ {
+ label: t('generator.views.database.table.tableSchema'),
+ field: 'tableSchema',
+ component: 'Input',
+ componentProps: {},
+ },
+ ] as FormSchema[];
+};
+
+/**
+ * 搜索表单配置
+ * @param t
+ */
+export const searchForm: (t: Function) => SmartSearchFormSchema[] = (t: Function) => {
+ return [
+ {
+ field: 'connectionName',
+ component: 'Input',
+ componentProps: {
+ placeholder: t('generator.views.database.table.connectionName'),
+ },
+ colProps: { span: 6 },
+ searchSymbol: 'likeRight',
+ label: '',
+ },
+ {
+ field: 'databaseName',
+ component: 'Input',
+ componentProps: {
+ placeholder: t('generator.views.database.table.databaseName'),
+ },
+ colProps: { span: 6 },
+ searchSymbol: '=',
+ label: '',
+ },
+ {
+ field: 'project',
+ component: 'Input',
+ componentProps: {
+ placeholder: t('generator.views.database.table.project'),
+ },
+ colProps: { span: 6 },
+ searchSymbol: 'likeLeft',
+ label: '',
+ },
+ ];
+};
diff --git a/src/modules/codeGenerator/views/database/DatabaseListView.vue b/src/modules/codeGenerator/views/database/DatabaseListView.vue
new file mode 100644
index 000000000..2485f914e
--- /dev/null
+++ b/src/modules/codeGenerator/views/database/DatabaseListView.vue
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/database/components/DatabaseListViewAddEditModal.vue b/src/modules/codeGenerator/views/database/components/DatabaseListViewAddEditModal.vue
new file mode 100644
index 000000000..3a5d44da5
--- /dev/null
+++ b/src/modules/codeGenerator/views/database/components/DatabaseListViewAddEditModal.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/database/components/TemplateSelected.vue b/src/modules/codeGenerator/views/database/components/TemplateSelected.vue
new file mode 100644
index 000000000..aa18c5e8d
--- /dev/null
+++ b/src/modules/codeGenerator/views/database/components/TemplateSelected.vue
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/database/components/TemplateSelectedModal.vue b/src/modules/codeGenerator/views/database/components/TemplateSelectedModal.vue
new file mode 100644
index 000000000..79acff999
--- /dev/null
+++ b/src/modules/codeGenerator/views/database/components/TemplateSelectedModal.vue
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/database/lang/en_US.ts b/src/modules/codeGenerator/views/database/lang/en_US.ts
new file mode 100644
index 000000000..241240be1
--- /dev/null
+++ b/src/modules/codeGenerator/views/database/lang/en_US.ts
@@ -0,0 +1,40 @@
+export default {
+ generator: {
+ views: {
+ database: {
+ common: {
+ chooseTemplate: 'Select template',
+ },
+ table: {
+ connectionName: 'Connection name',
+ databaseName: 'DB name',
+ type: 'Type',
+ project: 'Project',
+ url: 'URL',
+ username: 'Username',
+ tableSchema: 'Table schema',
+ password: 'Password',
+ },
+ button: {
+ testConnected: 'Test connection',
+ createDic: 'Generate database dic',
+ },
+ validate: {
+ type: 'Please select database type',
+ connectionName: 'Please enter connection name',
+ databaseName: 'Please enter database name',
+ project: 'Please enter database',
+ url: 'Please enter URL',
+ username: 'Please enter username',
+ password: 'Please enter password',
+ template: 'Please select template',
+ },
+ message: {
+ deleteOwn: 'You can only delete database connections that you have created',
+ connectSuccess: 'Database connection succeeded',
+ connectFail: 'Database connection failed',
+ },
+ },
+ },
+ },
+};
diff --git a/src/modules/codeGenerator/views/database/lang/zh_CN.ts b/src/modules/codeGenerator/views/database/lang/zh_CN.ts
new file mode 100644
index 000000000..f374fc48d
--- /dev/null
+++ b/src/modules/codeGenerator/views/database/lang/zh_CN.ts
@@ -0,0 +1,40 @@
+export default {
+ generator: {
+ views: {
+ database: {
+ common: {
+ chooseTemplate: '选择模板',
+ },
+ table: {
+ connectionName: '连接名称',
+ databaseName: '数据库名称',
+ type: '类型',
+ project: '项目',
+ url: 'URL',
+ username: '用户名',
+ tableSchema: 'TableSchema',
+ password: '密码',
+ },
+ button: {
+ testConnected: '测试连接',
+ createDic: '生成数据库字典',
+ },
+ validate: {
+ type: '请选择数据库类型',
+ connectionName: '请输入连接名称',
+ databaseName: '请输入数据库名称',
+ project: '请输入项目',
+ url: '请输入URL',
+ username: '请输入用户名',
+ password: '请输入密码',
+ template: '请选择模板',
+ },
+ message: {
+ deleteOwn: '只能删除自己创建的数据库连接',
+ connectSuccess: '数据库连接成功',
+ connectFail: '数据库连接失败',
+ },
+ },
+ },
+ },
+};
diff --git a/src/modules/codeGenerator/views/document/TemplateDataDocumentView.vue b/src/modules/codeGenerator/views/document/TemplateDataDocumentView.vue
new file mode 100644
index 000000000..0fa676d02
--- /dev/null
+++ b/src/modules/codeGenerator/views/document/TemplateDataDocumentView.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/template/CodeTemplateList.api.ts b/src/modules/codeGenerator/views/template/CodeTemplateList.api.ts
new file mode 100644
index 000000000..b6ab23b84
--- /dev/null
+++ b/src/modules/codeGenerator/views/template/CodeTemplateList.api.ts
@@ -0,0 +1,39 @@
+import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
+
+enum Api {
+ list = 'db/code/template/list',
+ saveUpdate = 'db/code/template/saveUpdate',
+ delete = 'db/code/template/batchDeleteById',
+ getById = 'db/code/template/getById',
+}
+
+export const listApi = (params) =>
+ defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: Api.list,
+ data: params,
+ });
+
+export const saveUpdateApi = (model) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: Api.saveUpdate,
+ data: model,
+ });
+};
+
+export const deleteApi = (ids: number[]) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: Api.delete,
+ data: ids,
+ });
+};
+
+export const getByIdApi = (id: number) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_CODE,
+ url: Api.getById,
+ data: id,
+ });
+};
diff --git a/src/modules/codeGenerator/views/template/CodeTemplateList.config.ts b/src/modules/codeGenerator/views/template/CodeTemplateList.config.ts
new file mode 100644
index 000000000..2b0531639
--- /dev/null
+++ b/src/modules/codeGenerator/views/template/CodeTemplateList.config.ts
@@ -0,0 +1,160 @@
+import type { SmartColumn, SmartSearchFormSchema } from '@/components/SmartTable';
+import type { FormSchema } from '@/components/Form';
+
+import { TemplateType as templateTypeConstants } from '../../constants/DatabaseConstants';
+import { extensionLanguageMap } from '../../constants/Constants';
+
+export const getTableColumns = (t: Function): SmartColumn[] => {
+ return [
+ {
+ 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: 'language',
+ title: '{generator.views.template.table.language}',
+ width: 200,
+ },
+ {
+ field: 'remark',
+ title: '{generator.views.template.table.remark}',
+ minWidth: 200,
+ align: 'left',
+ headerAlign: 'center',
+ },
+ {
+ title: '{common.table.createTime}',
+ field: 'createTime',
+ width: 165,
+ sortable: true,
+ },
+ {
+ title: '{common.table.createUser}',
+ field: 'createBy',
+ width: 120,
+ },
+ {
+ title: '{common.table.updateTime}',
+ field: 'updateTime',
+ width: 165,
+ sortable: true,
+ },
+ {
+ title: '{common.table.updateUser}',
+ field: 'updateBy',
+ width: 120,
+ },
+ {
+ title: '{common.table.operation}',
+ field: 'operation',
+ width: 120,
+ fixed: 'right',
+ slots: {
+ default: 'table-operation',
+ },
+ },
+ ];
+};
+
+export const getSearchSchemas = (t: Function): SmartSearchFormSchema[] => {
+ return [
+ {
+ label: t('generator.views.template.table.name'),
+ field: 'name',
+ component: 'Input',
+ searchSymbol: 'like',
+ },
+ ];
+};
+
+export const getAddEditFormSchemas = (t: Function): FormSchema[] => {
+ return [
+ {
+ label: '',
+ field: 'templateId',
+ component: 'Input',
+ show: false,
+ },
+ {
+ label: '',
+ field: 'groupId',
+ component: 'Input',
+ show: false,
+ },
+ {
+ label: t('generator.views.template.table.templateType'),
+ field: 'templateType',
+ component: 'Select',
+ required: true,
+ componentProps: {
+ options: Object.keys(templateTypeConstants).map((item) => {
+ const value = templateTypeConstants[item];
+ return {
+ value: value.value,
+ label: t(value.label),
+ };
+ }),
+ },
+ },
+ {
+ label: t('generator.views.template.table.name'),
+ field: 'name',
+ component: 'Input',
+ required: true,
+ },
+ {
+ label: t('generator.views.template.table.remark'),
+ field: 'remark',
+ component: 'Input',
+ },
+ {
+ label: t('generator.views.template.table.filenameSuffix'),
+ field: 'filenameSuffix',
+ component: 'Input',
+ },
+ {
+ label: t('generator.views.template.table.language'),
+ field: 'language',
+ component: 'Select',
+ componentProps: {
+ options: Object.keys(extensionLanguageMap).map((item) => {
+ return {
+ label: extensionLanguageMap[item],
+ value: item,
+ };
+ }),
+ },
+ },
+ {
+ label: '',
+ field: 'template',
+ slot: 'addEditForm-language',
+ colProps: {
+ span: 24,
+ },
+ labelWidth: 0,
+ disabledLabelWidth: true,
+ },
+ ];
+};
diff --git a/src/modules/codeGenerator/views/template/CodeTemplateList.vue b/src/modules/codeGenerator/views/template/CodeTemplateList.vue
new file mode 100644
index 000000000..1de9786aa
--- /dev/null
+++ b/src/modules/codeGenerator/views/template/CodeTemplateList.vue
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/template/components/TemplateGroup.vue b/src/modules/codeGenerator/views/template/components/TemplateGroup.vue
new file mode 100644
index 000000000..b6ac70206
--- /dev/null
+++ b/src/modules/codeGenerator/views/template/components/TemplateGroup.vue
@@ -0,0 +1,248 @@
+
+
+
+
+
+
+ {{ row.groupName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/template/components/TemplateSetUserGroup.vue b/src/modules/codeGenerator/views/template/components/TemplateSetUserGroup.vue
new file mode 100644
index 000000000..3e5edb478
--- /dev/null
+++ b/src/modules/codeGenerator/views/template/components/TemplateSetUserGroup.vue
@@ -0,0 +1,171 @@
+
+
+
+ {{ $t('generator.views.template.title.userGroup') }}
+
+
+
+
+
+
+
+
+
+ {{ $t('common.button.save') }}
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/codeGenerator/views/template/lang/en_US.ts b/src/modules/codeGenerator/views/template/lang/en_US.ts
new file mode 100644
index 000000000..0dad99a32
--- /dev/null
+++ b/src/modules/codeGenerator/views/template/lang/en_US.ts
@@ -0,0 +1,37 @@
+export default {
+ generator: {
+ views: {
+ template: {
+ label: {
+ templateType: {
+ templateCode: 'Code template',
+ templateDbDict: 'DB dict template',
+ },
+ },
+ title: {
+ userGroup: 'User group',
+ templateGroup: 'Template group',
+ seq: 'Seq',
+ },
+ table: {
+ name: 'Name',
+ templateType: 'Template Type',
+ language: 'Language',
+ remark: 'Remark',
+ filenameSuffix: 'Filename Suffix',
+ },
+ notice: {
+ onlyDeleteMy: 'Only self created templates can be deleted',
+ choseGroup: 'Please select a template group first',
+ },
+ validate: {
+ templateType: 'Please enter template type',
+ name: 'Please enter name',
+ remark: 'Please enter remark',
+ seq: 'Please enter seq',
+ templateGroup: 'Please enter template group',
+ },
+ },
+ },
+ },
+};
diff --git a/src/modules/codeGenerator/views/template/lang/zh_CN.ts b/src/modules/codeGenerator/views/template/lang/zh_CN.ts
new file mode 100644
index 000000000..b7f1b632f
--- /dev/null
+++ b/src/modules/codeGenerator/views/template/lang/zh_CN.ts
@@ -0,0 +1,37 @@
+export default {
+ generator: {
+ views: {
+ template: {
+ label: {
+ templateType: {
+ templateCode: '代码模板',
+ templateDbDict: '数据库字典模板',
+ },
+ },
+ title: {
+ userGroup: '用户组',
+ templateGroup: '模板分组',
+ seq: '序号',
+ },
+ table: {
+ name: '名称',
+ templateType: '模板类型',
+ language: '语言',
+ remark: '备注',
+ filenameSuffix: '文件名后缀',
+ },
+ notice: {
+ onlyDeleteMy: '只能删除自己创建的模板',
+ choseGroup: '请先选择模板分组',
+ },
+ validate: {
+ templateType: '请输入模板类型',
+ name: '请输入模板名称',
+ remark: '请输入备注',
+ seq: '请输入序号',
+ templateGroup: '请输入模板分组',
+ },
+ },
+ },
+ },
+};
diff --git a/src/modules/system/views/accessSecret/SysAuthAccessSecretListView.api.ts b/src/modules/system/views/accessSecret/SysAuthAccessSecretListView.api.ts
new file mode 100644
index 000000000..94268ef3e
--- /dev/null
+++ b/src/modules/system/views/accessSecret/SysAuthAccessSecretListView.api.ts
@@ -0,0 +1,42 @@
+import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
+
+enum Api {
+ list = '/sys/auth/accessSecret/list',
+ getById = '/sys/auth/accessSecret/getById',
+ saveUpdate = '/sys/auth/accessSecret/saveUpdate',
+ delete = '/sys/auth/accessSecret/batchDeleteById',
+}
+
+export const listApi = (params) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_SYSTEM,
+ url: Api.list,
+ data: {
+ ...params,
+ },
+ });
+};
+
+export const saveUpdateApi = (modelList: any[]) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_SYSTEM,
+ url: Api.saveUpdate,
+ data: modelList[0],
+ });
+};
+
+export const deleteApi = (removeRecords: Recordable[]) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_SYSTEM,
+ url: Api.delete,
+ data: removeRecords.map((item) => item.id),
+ });
+};
+
+export const getByIdApi = (id: number) => {
+ return defHttp.post({
+ service: ApiServiceEnum.SMART_SYSTEM,
+ url: Api.getById,
+ data: id,
+ });
+};
diff --git a/src/modules/system/views/accessSecret/SysAuthAccessSecretListView.config.ts b/src/modules/system/views/accessSecret/SysAuthAccessSecretListView.config.ts
new file mode 100644
index 000000000..6b1e508ac
--- /dev/null
+++ b/src/modules/system/views/accessSecret/SysAuthAccessSecretListView.config.ts
@@ -0,0 +1,186 @@
+import type { SmartColumn, SmartSearchFormSchema } from '@/components/SmartTable';
+import type { FormSchema } from '@/components/Form';
+
+import { tableUseYnClass } from '@/components/SmartTable';
+
+/**
+ * 表格列表
+ */
+export const getTableColumns = (): SmartColumn[] => {
+ return [
+ {
+ type: 'checkbox',
+ width: 60,
+ align: 'center',
+ fixed: 'left',
+ },
+ {
+ field: 'seq',
+ sortable: true,
+ title: '{common.table.seq}',
+ width: 100,
+ },
+ {
+ field: 'accessKey',
+ title: '{system.views.auth.acccessSecret.title.accessKey}',
+ width: 120,
+ },
+ {
+ field: 'secretKey',
+ title: '{system.views.auth.acccessSecret.title.secretKey}',
+ width: 120,
+ },
+ {
+ field: 'expireDate',
+ title: '{system.views.auth.acccessSecret.title.expireDate}',
+ width: 165,
+ },
+ {
+ field: 'accessIp',
+ title: '{system.views.auth.acccessSecret.title.accessIp}',
+ width: 120,
+ },
+ {
+ field: 'remark',
+ title: '{common.table.remark}',
+ width: 200,
+ },
+ {
+ ...tableUseYnClass(),
+ },
+ {
+ field: 'createBy',
+ title: '{common.table.createUser}',
+ width: 120,
+ },
+ {
+ field: 'createTime',
+ title: '{common.table.createTime}',
+ width: 165,
+ },
+ {
+ field: 'updateBy',
+ title: '{common.table.updateUser}',
+ width: 120,
+ },
+ {
+ field: 'updateTime',
+ title: '{common.table.updateTime}',
+ width: 165,
+ },
+ {
+ title: '{common.table.operation}',
+ field: 'operation',
+ width: 120,
+ fixed: 'right',
+ slots: {
+ default: 'table-operation',
+ },
+ },
+ ];
+};
+
+/**
+ * 添加修改表单
+ */
+export const getFormSchemas = (t: Function): FormSchema[] => {
+ return [
+ {
+ field: 'id',
+ show: false,
+ label: '',
+ component: 'Input',
+ componentProps: {},
+ },
+ {
+ field: 'accessKey',
+ label: t('system.views.auth.acccessSecret.title.accessKey'),
+ component: 'Input',
+ componentProps: {},
+ dynamicDisabled: true,
+ },
+ {
+ field: 'secretKey',
+ label: t('system.views.auth.acccessSecret.title.secretKey'),
+ component: 'Input',
+ componentProps: {},
+ dynamicDisabled: true,
+ },
+ {
+ field: 'expireDate',
+ label: t('system.views.auth.acccessSecret.title.expireDate'),
+ component: 'DatePicker',
+ componentProps: {
+ showTime: true,
+ style: { width: '100%' },
+ },
+ },
+ {
+ field: 'accessIp',
+ label: t('system.views.auth.acccessSecret.title.accessIp'),
+ component: 'InputTextArea',
+ componentProps: {
+ placeholder: t('system.views.auth.acccessSecret.validate.accessIp'),
+ },
+ },
+ {
+ field: 'remark',
+ label: t('common.table.remark'),
+ component: 'InputTextArea',
+ componentProps: {},
+ },
+ {
+ field: 'useYn',
+ label: t('common.table.useYn'),
+ component: 'Switch',
+ componentProps: {},
+ defaultValue: true,
+ },
+ {
+ field: 'seq',
+ label: t('common.table.seq'),
+ component: 'InputNumber',
+ componentProps: {},
+ required: true,
+ },
+ ];
+};
+
+export const getSearchFormSchemas = (t: Function): SmartSearchFormSchema[] => {
+ return [
+ {
+ field: 'accessKey',
+ label: t('system.views.auth.acccessSecret.title.accessKey'),
+ component: 'Input',
+ searchSymbol: 'like',
+ },
+ {
+ field: 'secretKey',
+ label: t('system.views.auth.acccessSecret.title.secretKey'),
+ component: 'Input',
+ searchSymbol: 'like',
+ },
+ {
+ field: 'useYn',
+ label: t('common.table.useYn'),
+ component: 'Select',
+ searchSymbol: '=',
+ defaultValue: 1,
+ componentProps: {
+ style: {
+ width: '120px',
+ },
+ options: [
+ {
+ label: t('common.form.use'),
+ value: 1,
+ },
+ {
+ label: t('common.form.noUse'),
+ value: 0,
+ },
+ ],
+ },
+ },
+ ];
+};
diff --git a/src/modules/system/views/accessSecret/SysAuthAccessSecretListView.vue b/src/modules/system/views/accessSecret/SysAuthAccessSecretListView.vue
new file mode 100644
index 000000000..96b317ff0
--- /dev/null
+++ b/src/modules/system/views/accessSecret/SysAuthAccessSecretListView.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/system/views/accessSecret/lang/zh_CN.ts b/src/modules/system/views/accessSecret/lang/zh_CN.ts
new file mode 100644
index 000000000..887991458
--- /dev/null
+++ b/src/modules/system/views/accessSecret/lang/zh_CN.ts
@@ -0,0 +1,28 @@
+/**
+ * 国际化信息
+ */
+export default {
+ trans: true,
+ key: 'system.views.auth.acccessSecret',
+ data: {
+ title: {
+ accessKey: 'Access key',
+ secretKey: 'Secret key',
+ expireDate: '过期时间',
+ accessIp: '授权IP或域名',
+ createBy: 'createBy',
+ updateBy: 'updateBy',
+ },
+ validate: {
+ accessKey: '请输入Access key',
+ secretKey: '请输入Secret key',
+ expireDate: '请输入过期时间',
+ accessIp: '请输入授权IP或域名,以逗号分隔',
+ },
+ rules: {},
+ search: {
+ accessKey: '请输入Access key',
+ secretKey: '请输入Secret key',
+ },
+ },
+};
diff --git a/src/utils/http/axios/Axios.ts b/src/utils/http/axios/Axios.ts
index 4e6ad1d9d..a6b14ace9 100644
--- a/src/utils/http/axios/Axios.ts
+++ b/src/utils/http/axios/Axios.ts
@@ -1,5 +1,11 @@
import type { AxiosInstance, AxiosResponse, AxiosError, InternalAxiosRequestConfig } from 'axios';
-import type { SmartAxiosRequestConfig, RequestOptions, Result, UploadFileParams } from '#/axios';
+import type {
+ SmartAxiosRequestConfig,
+ RequestOptions,
+ Result,
+ UploadFileParams,
+ UploadFileItemParams,
+} from '#/axios';
import type { CreateAxiosOptions } from './axiosTransform';
import axios from 'axios';
import qs from 'qs';
@@ -9,6 +15,7 @@ import { cloneDeep } from 'lodash-es';
import { ContentTypeEnum, RequestEnum } from '@/enums/httpEnum';
import { useGlobSetting } from '@/hooks/setting';
import { downloadByData } from '@/utils/file/download';
+import { isArray } from 'xe-utils';
export * from './axiosTransform';
@@ -124,13 +131,23 @@ export class VAxios {
*/
uploadFile(config: SmartAxiosRequestConfig, params: UploadFileParams) {
const formData = new window.FormData();
- const customFilename = params.name || 'file';
+ // const customFilename = params.name || 'file';
- if (params.filename) {
- formData.append(customFilename, params.file, params.filename);
+ const file = params.file;
+ let uploadFileList: UploadFileItemParams[];
+ if (isArray(file)) {
+ uploadFileList = file;
} else {
- formData.append(customFilename, params.file);
+ uploadFileList = [file];
}
+ uploadFileList.forEach((item) => {
+ const customFilename = item.name || 'file';
+ if (item.filename) {
+ formData.append(customFilename, item.file, item.filename);
+ } else {
+ formData.append(customFilename, item.file);
+ }
+ });
if (params.data) {
Object.keys(params.data).forEach((key) => {
diff --git a/src/utils/http/axios/index.ts b/src/utils/http/axios/index.ts
index e8c63356f..372bfe250 100644
--- a/src/utils/http/axios/index.ts
+++ b/src/utils/http/axios/index.ts
@@ -104,8 +104,22 @@ const transform: AxiosTransform = {
config.url = `${urlPrefix}${config.url}`;
}
+ // 处理URL
+ const { isStandalone } = useGlobSetting();
+ if (!isStandalone) {
+ let spi = '';
+ if (!config.url?.startsWith('/')) {
+ spi = '/';
+ }
+ config.url = `${config.service}${spi}${config.url}`;
+ }
+
if (apiUrl && isString(apiUrl)) {
- config.url = `${apiUrl}${config.url}`;
+ let spi = '';
+ if (!config.url?.startsWith('/')) {
+ spi = '/';
+ }
+ config.url = `${apiUrl}${spi}${config.url}`;
}
const params = config.params || {};
const data = config.data || false;