diff --git a/apps/web-naive/src/views/infra/apiAccessLog/data.ts b/apps/web-naive/src/views/infra/apiAccessLog/data.ts new file mode 100644 index 000000000..e924c2470 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiAccessLog/data.ts @@ -0,0 +1,173 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { InfraApiAccessLogApi } from '#/api/infra/api-access-log'; + +import { useAccess } from '@vben/access'; + +import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils'; + +const { hasAccessByCodes } = useAccess(); + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'userId', + label: '用户编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入用户编号', + }, + }, + { + fieldName: 'userType', + label: '用户类型', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.USER_TYPE, 'number'), + allowClear: true, + placeholder: '请选择用户类型', + }, + }, + { + fieldName: 'applicationName', + label: '应用名', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入应用名', + }, + }, + { + fieldName: 'beginTime', + label: '请求时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + { + fieldName: 'duration', + label: '执行时长', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入执行时长', + }, + }, + { + fieldName: 'resultCode', + label: '结果码', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入结果码', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns( + onActionClick: OnActionClickFn, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '日志编号', + minWidth: 100, + }, + { + field: 'userId', + title: '用户编号', + minWidth: 100, + }, + { + field: 'userType', + title: '用户类型', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.USER_TYPE }, + }, + }, + { + field: 'applicationName', + title: '应用名', + minWidth: 150, + }, + { + field: 'requestMethod', + title: '请求方法', + minWidth: 80, + }, + { + field: 'requestUrl', + title: '请求地址', + minWidth: 300, + }, + { + field: 'beginTime', + title: '请求时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + field: 'duration', + title: '执行时长', + minWidth: 120, + formatter: ({ row }) => `${row.duration} ms`, + }, + { + field: 'resultCode', + title: '操作结果', + minWidth: 150, + formatter: ({ row }) => { + return row.resultCode === 0 ? '成功' : `失败(${row.resultMsg})`; + }, + }, + { + field: 'operateModule', + title: '操作模块', + minWidth: 150, + }, + { + field: 'operateName', + title: '操作名', + minWidth: 220, + }, + { + field: 'operateType', + title: '操作类型', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.INFRA_OPERATE_TYPE }, + }, + }, + { + field: 'operation', + title: '操作', + minWidth: 80, + align: 'center', + fixed: 'right', + cellRender: { + attrs: { + nameField: 'id', + nameTitle: 'API访问日志', + onClick: onActionClick, + }, + name: 'CellOperation', + options: [ + { + code: 'detail', + text: '详情', + show: hasAccessByCodes(['infra:api-access-log:query']), + }, + ], + }, + }, + ]; +} diff --git a/apps/web-naive/src/views/infra/apiAccessLog/index.vue b/apps/web-naive/src/views/infra/apiAccessLog/index.vue new file mode 100644 index 000000000..cc08a3310 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiAccessLog/index.vue @@ -0,0 +1,110 @@ + + + diff --git a/apps/web-naive/src/views/infra/apiAccessLog/modules/detail.vue b/apps/web-naive/src/views/infra/apiAccessLog/modules/detail.vue new file mode 100644 index 000000000..028e33f48 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiAccessLog/modules/detail.vue @@ -0,0 +1,106 @@ + + + diff --git a/apps/web-naive/src/views/infra/apiErrorLog/data.ts b/apps/web-naive/src/views/infra/apiErrorLog/data.ts new file mode 100644 index 000000000..0344c3104 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiErrorLog/data.ts @@ -0,0 +1,175 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { InfraApiErrorLogApi } from '#/api/infra/api-error-log'; + +import { useAccess } from '@vben/access'; + +import { + DICT_TYPE, + getDictOptions, + getRangePickerDefaultProps, + InfraApiErrorLogProcessStatusEnum, +} from '#/utils'; + +const { hasAccessByCodes } = useAccess(); + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'userId', + label: '用户编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入用户编号', + }, + }, + { + fieldName: 'userType', + label: '用户类型', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.USER_TYPE, 'number'), + allowClear: true, + placeholder: '请选择用户类型', + }, + }, + { + fieldName: 'applicationName', + label: '应用名', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入应用名', + }, + }, + { + fieldName: 'exceptionTime', + label: '异常时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + { + fieldName: 'processStatus', + label: '处理状态', + component: 'Select', + componentProps: { + options: getDictOptions( + DICT_TYPE.INFRA_API_ERROR_LOG_PROCESS_STATUS, + 'number', + ), + allowClear: true, + placeholder: '请选择处理状态', + }, + defaultValue: InfraApiErrorLogProcessStatusEnum.INIT, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns( + onActionClick: OnActionClickFn, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '日志编号', + minWidth: 100, + }, + { + field: 'userId', + title: '用户编号', + minWidth: 100, + }, + { + field: 'userType', + title: '用户类型', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.USER_TYPE }, + }, + }, + { + field: 'applicationName', + title: '应用名', + minWidth: 150, + }, + { + field: 'requestMethod', + title: '请求方法', + minWidth: 80, + }, + { + field: 'requestUrl', + title: '请求地址', + minWidth: 200, + }, + { + field: 'exceptionTime', + title: '异常发生时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + field: 'exceptionName', + title: '异常名', + minWidth: 180, + }, + { + field: 'processStatus', + title: '处理状态', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.INFRA_API_ERROR_LOG_PROCESS_STATUS }, + }, + }, + { + field: 'operation', + title: '操作', + minWidth: 200, + align: 'center', + fixed: 'right', + cellRender: { + attrs: { + nameField: 'id', + nameTitle: 'API错误日志', + onClick: onActionClick, + }, + name: 'CellOperation', + options: [ + { + code: 'detail', + text: '详情', + show: hasAccessByCodes(['infra:api-error-log:query']), + }, + { + code: 'done', + text: '已处理', + show: (row: InfraApiErrorLogApi.ApiErrorLog) => { + return ( + row.processStatus === InfraApiErrorLogProcessStatusEnum.INIT && + hasAccessByCodes(['infra:api-error-log:update-status']) + ); + }, + }, + { + code: 'ignore', + text: '已忽略', + show: (row: InfraApiErrorLogApi.ApiErrorLog) => { + return ( + row.processStatus === InfraApiErrorLogProcessStatusEnum.INIT && + hasAccessByCodes(['infra:api-error-log:update-status']) + ); + }, + }, + ], + }, + }, + ]; +} diff --git a/apps/web-naive/src/views/infra/apiErrorLog/index.vue b/apps/web-naive/src/views/infra/apiErrorLog/index.vue new file mode 100644 index 000000000..e00ffb269 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiErrorLog/index.vue @@ -0,0 +1,133 @@ + + + diff --git a/apps/web-naive/src/views/infra/apiErrorLog/modules/detail.vue b/apps/web-naive/src/views/infra/apiErrorLog/modules/detail.vue new file mode 100644 index 000000000..b27e2dd70 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiErrorLog/modules/detail.vue @@ -0,0 +1,104 @@ + + + diff --git a/apps/web-naive/src/views/infra/build/index.vue b/apps/web-naive/src/views/infra/build/index.vue new file mode 100644 index 000000000..93173cbd2 --- /dev/null +++ b/apps/web-naive/src/views/infra/build/index.vue @@ -0,0 +1,183 @@ + + + + diff --git a/apps/web-naive/src/views/infra/codegen/data.ts b/apps/web-naive/src/views/infra/codegen/data.ts new file mode 100644 index 000000000..b9b354a2a --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/data.ts @@ -0,0 +1,591 @@ +import type { Recordable } from '@vben/types'; + +import type { VbenFormSchema } from '#/adapter/form'; +import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { InfraCodegenApi } from '#/api/infra/codegen'; +import type { SystemMenuApi } from '#/api/system/menu'; + +import { h } from 'vue'; + +import { useAccess } from '@vben/access'; +import { IconifyIcon } from '@vben/icons'; +import { handleTree } from '@vben/utils'; + +import { getDataSourceConfigList } from '#/api/infra/data-source-config'; +import { getMenuList } from '#/api/system/menu'; +import { $t } from '#/locales'; +import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils'; + +const { hasAccessByCodes } = useAccess(); + +/** 导入数据库表的表单 */ +export function useImportTableFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'dataSourceConfigId', + label: '数据源', + component: 'ApiSelect', + componentProps: { + api: async () => { + const data = await getDataSourceConfigList(); + return data.map((item) => ({ + label: item.name, + value: item.id, + })); + }, + autoSelect: 'first', + placeholder: '请选择数据源', + }, + rules: 'selectRequired', + }, + { + fieldName: 'name', + label: '表名称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入表名称', + }, + }, + { + fieldName: 'comment', + label: '表描述', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入表描述', + }, + }, + ]; +} + +/** 导入数据库表表格列定义 */ +export function useImportTableColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { field: 'name', title: '表名称', minWidth: 200 }, + { field: 'comment', title: '表描述', minWidth: 200 }, + ]; +} + +/** 基本信息表单的 schema */ +export function useBasicInfoFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'tableName', + label: '表名称', + component: 'Input', + componentProps: { + placeholder: '请输入仓库名称', + }, + rules: 'required', + }, + { + fieldName: 'tableComment', + label: '表描述', + component: 'Input', + componentProps: { + placeholder: '请输入表描述', + }, + rules: 'required', + }, + { + fieldName: 'className', + label: '实体类名称', + component: 'Input', + componentProps: { + placeholder: '请输入实体类名称', + }, + rules: 'required', + help: '默认去除表名的前缀。如果存在重复,则需要手动添加前缀,避免 MyBatis 报 Alias 重复的问题。', + }, + { + fieldName: 'author', + label: '作者', + component: 'Input', + componentProps: { + placeholder: '请输入作者', + }, + rules: 'required', + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + rows: 3, + placeholder: '请输入备注', + }, + formItemClass: 'md:col-span-2', + }, + ]; +} + +/** 生成信息表单基础 schema */ +export function useGenerationInfoBaseFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Select', + fieldName: 'templateType', + label: '生成模板', + componentProps: { + options: getDictOptions( + DICT_TYPE.INFRA_CODEGEN_TEMPLATE_TYPE, + 'number', + ), + class: 'w-full', + }, + rules: 'selectRequired', + }, + { + component: 'Select', + fieldName: 'frontType', + label: '前端类型', + componentProps: { + options: getDictOptions(DICT_TYPE.INFRA_CODEGEN_FRONT_TYPE, 'number'), + class: 'w-full', + }, + rules: 'selectRequired', + }, + { + component: 'Select', + fieldName: 'scene', + label: '生成场景', + componentProps: { + options: getDictOptions(DICT_TYPE.INFRA_CODEGEN_SCENE, 'number'), + class: 'w-full', + }, + rules: 'selectRequired', + }, + { + fieldName: 'parentMenuId', + label: '上级菜单', + help: '分配到指定菜单下,例如 系统管理', + component: 'ApiTreeSelect', + componentProps: { + allowClear: true, + api: async () => { + const data = await getMenuList(); + data.unshift({ + id: 0, + name: '顶级菜单', + } as SystemMenuApi.Menu); + return handleTree(data); + }, + class: 'w-full', + labelField: 'name', + valueField: 'id', + childrenField: 'children', + placeholder: '请选择上级菜单', + filterTreeNode(input: string, node: Recordable) { + if (!input || input.length === 0) { + return true; + } + const name: string = node.label ?? ''; + if (!name) return false; + return name.includes(input) || $t(name).includes(input); + }, + showSearch: true, + treeDefaultExpandedKeys: [0], + }, + rules: 'selectRequired', + renderComponentContent() { + return { + title({ label, icon }: { icon: string; label: string }) { + const components = []; + if (!label) return ''; + if (icon) { + components.push(h(IconifyIcon, { class: 'size-4', icon })); + } + components.push(h('span', { class: '' }, $t(label || ''))); + return h('div', { class: 'flex items-center gap-1' }, components); + }, + }; + }, + }, + { + component: 'Input', + fieldName: 'moduleName', + label: '模块名', + help: '模块名,即一级目录,例如 system、infra、tool 等等', + rules: 'required', + }, + { + component: 'Input', + fieldName: 'businessName', + label: '业务名', + help: '业务名,即二级目录,例如 user、permission、dict 等等', + rules: 'required', + }, + { + component: 'Input', + fieldName: 'className', + label: '类名称', + help: '类名称(首字母大写),例如SysUser、SysMenu、SysDictData 等等', + rules: 'required', + }, + { + component: 'Input', + fieldName: 'classComment', + label: '类描述', + help: '用作类描述,例如 用户', + rules: 'required', + }, + ]; +} + +/** 树表信息 schema */ +export function useGenerationInfoTreeFormSchema( + columns: InfraCodegenApi.CodegenColumn[] = [], +): VbenFormSchema[] { + return [ + { + component: 'Divider', + fieldName: 'treeDivider', + label: '', + renderComponentContent: () => { + return { + default: () => ['树表信息'], + }; + }, + formItemClass: 'md:col-span-2', + }, + { + component: 'Select', + fieldName: 'treeParentColumnId', + label: '父编号字段', + help: '树显示的父编码字段名,例如 parent_Id', + componentProps: { + class: 'w-full', + allowClear: true, + placeholder: '请选择', + options: columns.map((column) => ({ + label: column.columnName, + value: column.id, + })), + }, + rules: 'selectRequired', + }, + { + component: 'Select', + fieldName: 'treeNameColumnId', + label: '名称字段', + help: '树节点显示的名称字段,一般是 name', + componentProps: { + class: 'w-full', + allowClear: true, + placeholder: '请选择名称字段', + options: columns.map((column) => ({ + label: column.columnName, + value: column.id, + })), + }, + rules: 'selectRequired', + }, + ]; +} + +/** 主子表信息 schema */ +export function useGenerationInfoSubTableFormSchema( + columns: InfraCodegenApi.CodegenColumn[] = [], + tables: InfraCodegenApi.CodegenTable[] = [], +): VbenFormSchema[] { + return [ + { + component: 'Divider', + fieldName: 'subDivider', + label: '', + renderComponentContent: () => { + return { + default: () => ['主子表信息'], + }; + }, + formItemClass: 'md:col-span-2', + }, + { + component: 'Select', + fieldName: 'masterTableId', + label: '关联的主表', + help: '关联主表(父表)的表名, 如:system_user', + componentProps: { + class: 'w-full', + allowClear: true, + placeholder: '请选择', + options: tables.map((table) => ({ + label: `${table.tableName}:${table.tableComment}`, + value: table.id, + })), + }, + rules: 'selectRequired', + }, + { + component: 'Select', + fieldName: 'subJoinColumnId', + label: '子表关联的字段', + help: '子表关联的字段, 如:user_id', + componentProps: { + class: 'w-full', + allowClear: true, + placeholder: '请选择', + options: columns.map((column) => ({ + label: `${column.columnName}:${column.columnComment}`, + value: column.id, + })), + }, + rules: 'selectRequired', + }, + { + component: 'RadioGroup', + fieldName: 'subJoinMany', + label: '关联关系', + help: '主表与子表的关联关系', + componentProps: { + class: 'w-full', + allowClear: true, + placeholder: '请选择', + options: [ + { + label: '一对多', + value: true, + }, + { + label: '一对一', + value: 'false', + }, + ], + }, + rules: 'required', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'tableName', + label: '表名称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入表名称', + }, + }, + { + fieldName: 'tableComment', + label: '表描述', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入表描述', + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns( + onActionClick: OnActionClickFn, + getDataSourceConfigName?: (dataSourceConfigId: number) => string | undefined, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'dataSourceConfigId', + title: '数据源', + minWidth: 120, + formatter: (row) => getDataSourceConfigName?.(row.cellValue) || '-', + }, + { + field: 'tableName', + title: '表名称', + minWidth: 200, + }, + { + field: 'tableComment', + title: '表描述', + minWidth: 200, + }, + { + field: 'className', + title: '实体', + minWidth: 200, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + field: 'updateTime', + title: '更新时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + field: 'operation', + title: '操作', + width: 300, + fixed: 'right', + align: 'center', + cellRender: { + attrs: { + nameField: 'tableName', + nameTitle: '代码生成', + onClick: onActionClick, + }, + name: 'CellOperation', + options: [ + { + code: 'preview', + text: '预览', + show: hasAccessByCodes(['infra:codegen:preview']), + }, + { + code: 'edit', + show: hasAccessByCodes(['infra:codegen:update']), + }, + { + code: 'delete', + show: hasAccessByCodes(['infra:codegen:delete']), + }, + { + code: 'sync', + text: '同步', + show: hasAccessByCodes(['infra:codegen:update']), + }, + { + code: 'generate', + text: '生成代码', + show: hasAccessByCodes(['infra:codegen:download']), + }, + ], + }, + }, + ]; +} + +/** 代码生成表格列定义 */ +export function useCodegenColumnTableColumns(): VxeTableGridOptions['columns'] { + return [ + { field: 'columnName', title: '字段列名', minWidth: 130 }, + { + field: 'columnComment', + title: '字段描述', + minWidth: 100, + slots: { default: 'columnComment' }, + }, + { field: 'dataType', title: '物理类型', minWidth: 100 }, + { + field: 'javaType', + title: 'Java 类型', + minWidth: 130, + slots: { default: 'javaType' }, + params: { + options: [ + { label: 'Long', value: 'Long' }, + { label: 'String', value: 'String' }, + { label: 'Integer', value: 'Integer' }, + { label: 'Double', value: 'Double' }, + { label: 'BigDecimal', value: 'BigDecimal' }, + { label: 'LocalDateTime', value: 'LocalDateTime' }, + { label: 'Boolean', value: 'Boolean' }, + ], + }, + }, + { + field: 'javaField', + title: 'Java 属性', + minWidth: 100, + slots: { default: 'javaField' }, + }, + { + field: 'createOperation', + title: '插入', + width: 40, + slots: { default: 'createOperation' }, + }, + { + field: 'updateOperation', + title: '编辑', + width: 40, + slots: { default: 'updateOperation' }, + }, + { + field: 'listOperationResult', + title: '列表', + width: 40, + slots: { default: 'listOperationResult' }, + }, + { + field: 'listOperation', + title: '查询', + width: 40, + slots: { default: 'listOperation' }, + }, + { + field: 'listOperationCondition', + title: '查询方式', + minWidth: 100, + slots: { default: 'listOperationCondition' }, + params: { + options: [ + { label: '=', value: '=' }, + { label: '!=', value: '!=' }, + { label: '>', value: '>' }, + { label: '>=', value: '>=' }, + { label: '<', value: '<' }, + { label: '<=', value: '<=' }, + { label: 'LIKE', value: 'LIKE' }, + { label: 'BETWEEN', value: 'BETWEEN' }, + ], + }, + }, + { + field: 'nullable', + title: '允许空', + width: 60, + slots: { default: 'nullable' }, + }, + { + field: 'htmlType', + title: '显示类型', + width: 130, + slots: { default: 'htmlType' }, + params: { + options: [ + { label: '文本框', value: 'input' }, + { label: '文本域', value: 'textarea' }, + { label: '下拉框', value: 'select' }, + { label: '单选框', value: 'radio' }, + { label: '复选框', value: 'checkbox' }, + { label: '日期控件', value: 'datetime' }, + { label: '图片上传', value: 'imageUpload' }, + { label: '文件上传', value: 'fileUpload' }, + { label: '富文本控件', value: 'editor' }, + ], + }, + }, + { + field: 'dictType', + title: '字典类型', + width: 120, + slots: { default: 'dictType' }, + }, + { + field: 'example', + title: '示例', + minWidth: 100, + slots: { default: 'example' }, + }, + ]; +} diff --git a/apps/web-naive/src/views/infra/codegen/edit/index.vue b/apps/web-naive/src/views/infra/codegen/edit/index.vue new file mode 100644 index 000000000..62f29e6c2 --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/edit/index.vue @@ -0,0 +1,170 @@ + + + diff --git a/apps/web-naive/src/views/infra/codegen/index.vue b/apps/web-naive/src/views/infra/codegen/index.vue new file mode 100644 index 000000000..0a08f14f3 --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/index.vue @@ -0,0 +1,232 @@ + + diff --git a/apps/web-naive/src/views/infra/codegen/modules/basic-info.vue b/apps/web-naive/src/views/infra/codegen/modules/basic-info.vue new file mode 100644 index 000000000..00c49911b --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/modules/basic-info.vue @@ -0,0 +1,45 @@ + + diff --git a/apps/web-naive/src/views/infra/codegen/modules/column-info.vue b/apps/web-naive/src/views/infra/codegen/modules/column-info.vue new file mode 100644 index 000000000..36d05726f --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/modules/column-info.vue @@ -0,0 +1,161 @@ + + + diff --git a/apps/web-naive/src/views/infra/codegen/modules/generation-info.vue b/apps/web-naive/src/views/infra/codegen/modules/generation-info.vue new file mode 100644 index 000000000..da859ef2f --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/modules/generation-info.vue @@ -0,0 +1,172 @@ + + + diff --git a/apps/web-naive/src/views/infra/codegen/modules/import-table.vue b/apps/web-naive/src/views/infra/codegen/modules/import-table.vue new file mode 100644 index 000000000..c474179be --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/modules/import-table.vue @@ -0,0 +1,120 @@ + + + diff --git a/apps/web-naive/src/views/infra/codegen/modules/preview-code.vue b/apps/web-naive/src/views/infra/codegen/modules/preview-code.vue new file mode 100644 index 000000000..dfb312a11 --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/modules/preview-code.vue @@ -0,0 +1,372 @@ + + + + + diff --git a/apps/web-naive/src/views/infra/config/data.ts b/apps/web-naive/src/views/infra/config/data.ts new file mode 100644 index 000000000..1a79bc3b2 --- /dev/null +++ b/apps/web-naive/src/views/infra/config/data.ts @@ -0,0 +1,209 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { InfraConfigApi } from '#/api/infra/config'; + +import { useAccess } from '@vben/access'; + +import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils'; + +const { hasAccessByCodes } = useAccess(); + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'id', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'category', + label: '参数分类', + component: 'Input', + componentProps: { + placeholder: '请输入参数分类', + }, + rules: 'required', + }, + { + fieldName: 'name', + label: '参数名称', + component: 'Input', + componentProps: { + placeholder: '请输入参数名称', + }, + rules: 'required', + }, + { + fieldName: 'key', + label: '参数键名', + component: 'Input', + componentProps: { + placeholder: '请输入参数键名', + }, + rules: 'required', + }, + { + fieldName: 'value', + label: '参数键值', + component: 'Input', + componentProps: { + placeholder: '请输入参数键值', + }, + rules: 'required', + }, + { + fieldName: 'visible', + label: '是否可见', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING, 'boolean'), + buttonStyle: 'solid', + optionType: 'button', + }, + defaultValue: true, + rules: 'required', + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '参数名称', + component: 'Input', + componentProps: { + placeholder: '请输入参数名称', + clearable: true, + }, + }, + { + fieldName: 'key', + label: '参数键名', + component: 'Input', + componentProps: { + placeholder: '请输入参数键名', + clearable: true, + }, + }, + { + fieldName: 'type', + label: '系统内置', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.INFRA_CONFIG_TYPE, 'number'), + placeholder: '请选择系统内置', + allowClear: true, + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns( + onActionClick: OnActionClickFn, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '参数主键', + minWidth: 100, + }, + { + field: 'category', + title: '参数分类', + minWidth: 120, + }, + { + field: 'name', + title: '参数名称', + minWidth: 200, + }, + { + field: 'key', + title: '参数键名', + minWidth: 200, + }, + { + field: 'value', + title: '参数键值', + minWidth: 150, + }, + { + field: 'visible', + title: '是否可见', + minWidth: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, + }, + }, + { + field: 'type', + title: '系统内置', + minWidth: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.INFRA_CONFIG_TYPE }, + }, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + field: 'operation', + title: '操作', + minWidth: 130, + align: 'center', + fixed: 'right', + cellRender: { + attrs: { + nameField: 'name', + nameTitle: '参数', + onClick: onActionClick, + }, + name: 'CellOperation', + options: [ + { + code: 'edit', + show: hasAccessByCodes(['infra:config:update']), + }, + { + code: 'delete', + show: hasAccessByCodes(['infra:config:delete']), + }, + ], + }, + }, + ]; +} diff --git a/apps/web-naive/src/views/infra/config/index.vue b/apps/web-naive/src/views/infra/config/index.vue new file mode 100644 index 000000000..788e84b78 --- /dev/null +++ b/apps/web-naive/src/views/infra/config/index.vue @@ -0,0 +1,134 @@ + + + diff --git a/apps/web-naive/src/views/infra/config/modules/form.vue b/apps/web-naive/src/views/infra/config/modules/form.vue new file mode 100644 index 000000000..837fa1f45 --- /dev/null +++ b/apps/web-naive/src/views/infra/config/modules/form.vue @@ -0,0 +1,81 @@ + + + diff --git a/apps/web-naive/src/views/infra/dataSourceConfig/data.ts b/apps/web-naive/src/views/infra/dataSourceConfig/data.ts new file mode 100644 index 000000000..c22a368ad --- /dev/null +++ b/apps/web-naive/src/views/infra/dataSourceConfig/data.ts @@ -0,0 +1,119 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { InfraDataSourceConfigApi } from '#/api/infra/data-source-config'; + +import { useAccess } from '@vben/access'; + +const { hasAccessByCodes } = useAccess(); + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'id', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '数据源名称', + component: 'Input', + componentProps: { + placeholder: '请输入数据源名称', + }, + rules: 'required', + }, + { + fieldName: 'url', + label: '数据源连接', + component: 'Input', + componentProps: { + placeholder: '请输入数据源连接', + }, + rules: 'required', + }, + { + fieldName: 'username', + label: '用户名', + component: 'Input', + componentProps: { + placeholder: '请输入用户名', + }, + rules: 'required', + }, + { + fieldName: 'password', + label: '密码', + component: 'Input', + componentProps: { + placeholder: '请输入密码', + type: 'password', + }, + rules: 'required', + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns( + onActionClick: OnActionClickFn, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '主键编号', + minWidth: 100, + }, + { + field: 'name', + title: '数据源名称', + minWidth: 150, + }, + { + field: 'url', + title: '数据源连接', + minWidth: 300, + }, + { + field: 'username', + title: '用户名', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + field: 'operation', + title: '操作', + minWidth: 130, + align: 'center', + fixed: 'right', + cellRender: { + attrs: { + nameField: 'name', + nameTitle: '数据源', + onClick: onActionClick, + }, + name: 'CellOperation', + options: [ + { + code: 'edit', + show: hasAccessByCodes(['infra:data-source-config:update']), + disabled: (row: any) => row.id === 0, + }, + { + code: 'delete', + show: hasAccessByCodes(['infra:data-source-config:delete']), + disabled: (row: any) => row.id === 0, + }, + ], + }, + }, + ]; +} diff --git a/apps/web-naive/src/views/infra/dataSourceConfig/index.vue b/apps/web-naive/src/views/infra/dataSourceConfig/index.vue new file mode 100644 index 000000000..339d75e4c --- /dev/null +++ b/apps/web-naive/src/views/infra/dataSourceConfig/index.vue @@ -0,0 +1,123 @@ + + + diff --git a/apps/web-naive/src/views/infra/dataSourceConfig/modules/form.vue b/apps/web-naive/src/views/infra/dataSourceConfig/modules/form.vue new file mode 100644 index 000000000..c4d585d29 --- /dev/null +++ b/apps/web-naive/src/views/infra/dataSourceConfig/modules/form.vue @@ -0,0 +1,88 @@ + + + diff --git a/apps/web-naive/src/views/infra/druid/index.vue b/apps/web-naive/src/views/infra/druid/index.vue new file mode 100644 index 000000000..eb91f8d47 --- /dev/null +++ b/apps/web-naive/src/views/infra/druid/index.vue @@ -0,0 +1,38 @@ + + +