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..742ee4de1 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiAccessLog/data.ts @@ -0,0 +1,270 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { InfraApiAccessLogApi } from '#/api/infra/api-access-log'; +import type { DescriptionItemSchema } from '#/components/description'; + +import { h } from 'vue'; + +import { JsonViewer } from '@vben/common-ui'; +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +import { formatDateTime } from '@vben/utils'; + +import { DictTag } from '#/components/dict-tag'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 列表的搜索表单 */ +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: 'DatePicker', + 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(): 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: ({ cellValue }) => `${cellValue} 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 }, + }, + }, + { + title: '操作', + width: 80, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 详情页的字段 */ +export function useDetailSchema(): DescriptionItemSchema[] { + return [ + { + field: 'id', + label: '日志编号', + }, + { + field: 'traceId', + label: '链路追踪', + }, + { + field: 'applicationName', + label: '应用名', + }, + { + field: 'userId', + label: '用户Id', + }, + { + field: 'userType', + label: '用户类型', + content: (data: InfraApiAccessLogApi.ApiAccessLog) => { + return h(DictTag, { + type: DICT_TYPE.USER_TYPE, + value: data.userType, + }); + }, + }, + { + field: 'userIp', + label: '用户 IP', + }, + { + field: 'userAgent', + label: '用户 UA', + }, + { + label: '请求信息', + content: (data: InfraApiAccessLogApi.ApiAccessLog) => { + if (data?.requestMethod && data?.requestUrl) { + return `${data.requestMethod} ${data.requestUrl}`; + } + return ''; + }, + }, + { + field: 'requestParams', + label: '请求参数', + content: (data: InfraApiAccessLogApi.ApiAccessLog) => { + if (data.requestParams) { + return h(JsonViewer, { + value: JSON.parse(data.requestParams), + previewMode: true, + }); + } + return ''; + }, + }, + { + field: 'responseBody', + label: '请求结果', + }, + { + label: '请求时间', + content: (data: InfraApiAccessLogApi.ApiAccessLog) => { + if (data?.beginTime && data?.endTime) { + return `${formatDateTime(data.beginTime)} ~ ${formatDateTime(data.endTime)}`; + } + return ''; + }, + }, + { + label: '请求耗时', + content: (data: InfraApiAccessLogApi.ApiAccessLog) => { + return data?.duration ? `${data.duration} ms` : ''; + }, + }, + { + label: '操作结果', + content: (data: InfraApiAccessLogApi.ApiAccessLog) => { + if (data?.resultCode === 0) { + return '正常'; + } else if (data && data.resultCode > 0) { + return `失败 | ${data.resultCode} | ${data.resultMsg}`; + } + return ''; + }, + }, + { + field: 'operateModule', + label: '操作模块', + }, + { + field: 'operateName', + label: '操作名', + }, + { + field: 'operateType', + label: '操作类型', + content: (data: InfraApiAccessLogApi.ApiAccessLog) => { + return h(DictTag, { + type: DICT_TYPE.INFRA_OPERATE_TYPE, + value: data?.operateType, + }); + }, + }, + ]; +} 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..af7cc0136 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiAccessLog/index.vue @@ -0,0 +1,107 @@ + + + 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..70869fe38 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiAccessLog/modules/detail.vue @@ -0,0 +1,53 @@ + + + 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..040caafa4 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiErrorLog/data.ts @@ -0,0 +1,251 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { InfraApiErrorLogApi } from '#/api/infra/api-error-log'; +import type { DescriptionItemSchema } from '#/components/description'; + +import { h } from 'vue'; + +import { JsonViewer } from '@vben/common-ui'; +import { DICT_TYPE, InfraApiErrorLogProcessStatusEnum } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +import { formatDateTime } from '@vben/utils'; + +import { DictTag } from '#/components/dict-tag'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 列表的搜索表单 */ +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: 'DatePicker', + 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(): 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 }, + }, + }, + { + title: '操作', + minWidth: 220, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 详情页的字段 */ +export function useDetailSchema(): DescriptionItemSchema[] { + return [ + { + field: 'id', + label: '日志编号', + }, + { + field: 'traceId', + label: '链路追踪', + }, + { + field: 'applicationName', + label: '应用名', + }, + { + field: 'userId', + label: '用户Id', + }, + { + field: 'userType', + label: '用户类型', + content: (data: InfraApiErrorLogApi.ApiErrorLog) => { + return h(DictTag, { + type: DICT_TYPE.USER_TYPE, + value: data.userType, + }); + }, + }, + { + field: 'userIp', + label: '用户 IP', + }, + { + field: 'userAgent', + label: '用户 UA', + }, + { + field: 'requestMethod', + label: '请求信息', + content: (data: InfraApiErrorLogApi.ApiErrorLog) => { + if (data?.requestMethod && data?.requestUrl) { + return `${data.requestMethod} ${data.requestUrl}`; + } + return ''; + }, + }, + { + field: 'requestParams', + label: '请求参数', + content: (data: InfraApiErrorLogApi.ApiErrorLog) => { + if (data.requestParams) { + return h(JsonViewer, { + value: JSON.parse(data.requestParams), + previewMode: true, + }); + } + return ''; + }, + }, + { + field: 'exceptionTime', + label: '异常时间', + content: (data: InfraApiErrorLogApi.ApiErrorLog) => { + return formatDateTime(data?.exceptionTime || '') as string; + }, + }, + { + field: 'exceptionName', + label: '异常名', + }, + { + field: 'exceptionStackTrace', + label: '异常堆栈', + hidden: (data: InfraApiErrorLogApi.ApiErrorLog) => + !data?.exceptionStackTrace, + content: (data: InfraApiErrorLogApi.ApiErrorLog) => { + if (data?.exceptionStackTrace) { + return h('textarea', { + value: data.exceptionStackTrace, + style: + 'width: 100%; min-height: 200px; max-height: 400px; resize: vertical;', + readonly: true, + }); + } + return ''; + }, + }, + { + field: 'processStatus', + label: '处理状态', + content: (data: InfraApiErrorLogApi.ApiErrorLog) => { + return h(DictTag, { + type: DICT_TYPE.INFRA_API_ERROR_LOG_PROCESS_STATUS, + value: data?.processStatus, + }); + }, + }, + { + field: 'processUserId', + label: '处理人', + hidden: (data: InfraApiErrorLogApi.ApiErrorLog) => !data?.processUserId, + }, + { + field: 'processTime', + label: '处理时间', + hidden: (data: InfraApiErrorLogApi.ApiErrorLog) => !data?.processTime, + content: (data: InfraApiErrorLogApi.ApiErrorLog) => { + return formatDateTime(data?.processTime || '') as string; + }, + }, + ]; +} 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..ad9748be8 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiErrorLog/index.vue @@ -0,0 +1,155 @@ + + + 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..3d4836696 --- /dev/null +++ b/apps/web-naive/src/views/infra/apiErrorLog/modules/detail.vue @@ -0,0 +1,53 @@ + + + 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..a976d982f --- /dev/null +++ b/apps/web-naive/src/views/infra/build/index.vue @@ -0,0 +1,9 @@ + + + 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..e97825b83 --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/data.ts @@ -0,0 +1,557 @@ +import type { Recordable } from '@vben/types'; + +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { InfraCodegenApi } from '#/api/infra/codegen'; +import type { SystemMenuApi } from '#/api/system/menu'; + +import { h } from 'vue'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +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 { getRangePickerDefaultProps } from '#/utils'; + +/** 导入数据库表的表单 */ +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: 'Input', + componentProps: { + type: 'textarea', + 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: 'DatePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns( + getDataSourceConfigName?: (dataSourceConfigId: number) => string | undefined, +): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { + field: 'dataSourceConfigId', + title: '数据源', + minWidth: 120, + formatter: ({ cellValue }) => getDataSourceConfigName?.(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', + }, + { + title: '操作', + width: 280, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 代码生成表格列定义 */ +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..3018cbbee --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/edit/index.vue @@ -0,0 +1,164 @@ + + + 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..27cfeca04 --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/index.vue @@ -0,0 +1,283 @@ + + 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..e9343aff7 --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/modules/column-info.vue @@ -0,0 +1,153 @@ + + + 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..56ffe616f --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/modules/generation-info.vue @@ -0,0 +1,176 @@ + + + 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..1898bad7e --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/modules/import-table.vue @@ -0,0 +1,118 @@ + + + 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..d5a4e4327 --- /dev/null +++ b/apps/web-naive/src/views/infra/codegen/modules/preview-code.vue @@ -0,0 +1,268 @@ + + + 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..4b3a5162f --- /dev/null +++ b/apps/web-naive/src/views/infra/config/data.ts @@ -0,0 +1,188 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { getRangePickerDefaultProps } from '#/utils'; + +/** 新增/修改的表单 */ +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: 'Input', + componentProps: { + type: 'textarea', + placeholder: '请输入备注', + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '参数名称', + component: 'Input', + componentProps: { + placeholder: '请输入参数名称', + allowClear: true, + }, + }, + { + fieldName: 'key', + label: '参数键名', + component: 'Input', + componentProps: { + placeholder: '请输入参数键名', + allowClear: true, + }, + }, + { + fieldName: 'type', + label: '系统内置', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.INFRA_CONFIG_TYPE, 'number'), + placeholder: '请选择系统内置', + allowClear: true, + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'DatePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { + 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', + }, + { + title: '操作', + width: 160, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} 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..e1e5b1c51 --- /dev/null +++ b/apps/web-naive/src/views/infra/config/index.vue @@ -0,0 +1,183 @@ + + + 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..7a5a63994 --- /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..6f4c6027f --- /dev/null +++ b/apps/web-naive/src/views/infra/dataSourceConfig/data.ts @@ -0,0 +1,92 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +/** 新增/修改的表单 */ +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(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { + 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', + }, + { + title: '操作', + width: 160, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} 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..866b26b38 --- /dev/null +++ b/apps/web-naive/src/views/infra/dataSourceConfig/index.vue @@ -0,0 +1,159 @@ + + + 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..025707154 --- /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/demo/demo01/data.ts b/apps/web-naive/src/views/infra/demo/demo01/data.ts new file mode 100644 index 000000000..ac849cc8e --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo01/data.ts @@ -0,0 +1,152 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { Demo01ContactApi } from '#/api/infra/demo/demo01'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { getRangePickerDefaultProps } from '#/utils'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '名字', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入名字', + }, + }, + { + fieldName: 'sex', + label: '性别', + rules: 'required', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'), + buttonStyle: 'solid', + optionType: 'button', + }, + }, + { + fieldName: 'birthday', + label: '出生年', + rules: 'required', + component: 'DatePicker', + componentProps: { + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + }, + }, + { + fieldName: 'description', + label: '简介', + rules: 'required', + component: 'RichTextarea', + }, + { + fieldName: 'avatar', + label: '头像', + component: 'ImageUpload', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '名字', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入名字', + }, + }, + { + fieldName: 'sex', + label: '性别', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'), + placeholder: '请选择性别', + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'DatePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { + field: 'id', + title: '编号', + minWidth: 120, + }, + { + field: 'name', + title: '名字', + minWidth: 120, + }, + { + field: 'sex', + title: '性别', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.SYSTEM_USER_SEX }, + }, + }, + { + field: 'birthday', + title: '出生年', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + field: 'description', + title: '简介', + minWidth: 120, + }, + { + field: 'avatar', + title: '头像', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 160, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-naive/src/views/infra/demo/demo01/index.vue b/apps/web-naive/src/views/infra/demo/demo01/index.vue new file mode 100644 index 000000000..c59c5bcf8 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo01/index.vue @@ -0,0 +1,185 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo01/modules/form.vue b/apps/web-naive/src/views/infra/demo/demo01/modules/form.vue new file mode 100644 index 000000000..09bfe8fe9 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo01/modules/form.vue @@ -0,0 +1,87 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo02/data.ts b/apps/web-naive/src/views/infra/demo/demo02/data.ts new file mode 100644 index 000000000..afd1b8034 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo02/data.ts @@ -0,0 +1,120 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { Demo02CategoryApi } from '#/api/infra/demo/demo02'; + +import { handleTree } from '@vben/utils'; + +import { getDemo02CategoryList } from '#/api/infra/demo/demo02'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'parentId', + label: '上级示例分类', + component: 'ApiTreeSelect', + componentProps: { + allowClear: true, + api: async () => { + const data = await getDemo02CategoryList({}); + data.unshift({ + id: 0, + name: '顶级示例分类', + }); + return handleTree(data); + }, + labelField: 'name', + valueField: 'id', + childrenField: 'children', + placeholder: '请选择上级示例分类', + treeDefaultExpandAll: true, + }, + rules: 'selectRequired', + }, + { + fieldName: 'name', + label: '名字', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入名字', + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '名字', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入名字', + }, + }, + { + fieldName: 'parentId', + label: '父级编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入父级编号', + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'DatePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '编号', + minWidth: 120, + }, + { + field: 'name', + title: '名字', + minWidth: 120, + treeNode: true, + }, + { + field: 'parentId', + title: '父级编号', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 220, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-naive/src/views/infra/demo/demo02/index.vue b/apps/web-naive/src/views/infra/demo/demo02/index.vue new file mode 100644 index 000000000..b7823cbfa --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo02/index.vue @@ -0,0 +1,175 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo02/modules/form.vue b/apps/web-naive/src/views/infra/demo/demo02/modules/form.vue new file mode 100644 index 000000000..c400afe33 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo02/modules/form.vue @@ -0,0 +1,90 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/erp/data.ts b/apps/web-naive/src/views/infra/demo/demo03/erp/data.ts new file mode 100644 index 000000000..503cb1b9b --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/erp/data.ts @@ -0,0 +1,381 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { Demo03StudentApi } from '#/api/infra/demo/demo03/erp'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { getRangePickerDefaultProps } from '#/utils'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '名字', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入名字', + }, + }, + { + fieldName: 'sex', + label: '性别', + rules: 'required', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'), + buttonStyle: 'solid', + optionType: 'button', + }, + }, + { + fieldName: 'birthday', + label: '出生日期', + rules: 'required', + component: 'DatePicker', + componentProps: { + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + }, + }, + { + fieldName: 'description', + label: '简介', + rules: 'required', + component: 'RichTextarea', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '名字', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入名字', + }, + }, + { + fieldName: 'sex', + label: '性别', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'), + placeholder: '请选择性别', + }, + }, + { + fieldName: 'description', + label: '简介', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入简介', + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'DatePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { + field: 'id', + title: '编号', + minWidth: 120, + }, + { + field: 'name', + title: '名字', + minWidth: 120, + }, + { + field: 'sex', + title: '性别', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.SYSTEM_USER_SEX }, + }, + }, + { + field: 'birthday', + title: '出生日期', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + field: 'description', + title: '简介', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 280, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +// ==================== 子表(学生课程) ==================== + +/** 新增/修改的表单 */ +export function useDemo03CourseFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '名字', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入名字', + }, + }, + { + fieldName: 'score', + label: '分数', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入分数', + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useDemo03CourseGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'studentId', + label: '学生编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入学生编号', + }, + }, + { + fieldName: 'name', + label: '名字', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入名字', + }, + }, + { + fieldName: 'score', + label: '分数', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入分数', + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'DatePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useDemo03CourseGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { + field: 'id', + title: '编号', + minWidth: 120, + }, + { + field: 'studentId', + title: '学生编号', + minWidth: 120, + }, + { + field: 'name', + title: '名字', + minWidth: 120, + }, + { + field: 'score', + title: '分数', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 280, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +// ==================== 子表(学生班级) ==================== + +/** 新增/修改的表单 */ +export function useDemo03GradeFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '名字', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入名字', + }, + }, + { + fieldName: 'teacher', + label: '班主任', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入班主任', + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useDemo03GradeGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'studentId', + label: '学生编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入学生编号', + }, + }, + { + fieldName: 'name', + label: '名字', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入名字', + }, + }, + { + fieldName: 'teacher', + label: '班主任', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入班主任', + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'DatePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useDemo03GradeGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { + field: 'id', + title: '编号', + minWidth: 120, + }, + { + field: 'studentId', + title: '学生编号', + minWidth: 120, + }, + { + field: 'name', + title: '名字', + minWidth: 120, + }, + { + field: 'teacher', + title: '班主任', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 280, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-naive/src/views/infra/demo/demo03/erp/index.vue b/apps/web-naive/src/views/infra/demo/demo03/erp/index.vue new file mode 100644 index 000000000..edbc69e04 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/erp/index.vue @@ -0,0 +1,209 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-course-form.vue b/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-course-form.vue new file mode 100644 index 000000000..98b7991e2 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-course-form.vue @@ -0,0 +1,91 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-course-list.vue b/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-course-list.vue new file mode 100644 index 000000000..09ea3e573 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-course-list.vue @@ -0,0 +1,197 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-grade-form.vue b/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-grade-form.vue new file mode 100644 index 000000000..70ba1a775 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-grade-form.vue @@ -0,0 +1,92 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-grade-list.vue b/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-grade-list.vue new file mode 100644 index 000000000..821c290d2 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/erp/modules/demo03-grade-list.vue @@ -0,0 +1,200 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/erp/modules/form.vue b/apps/web-naive/src/views/infra/demo/demo03/erp/modules/form.vue new file mode 100644 index 000000000..3bbf9e6af --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/erp/modules/form.vue @@ -0,0 +1,88 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/inner/data.ts b/apps/web-naive/src/views/infra/demo/demo03/inner/data.ts new file mode 100644 index 000000000..986b4ac66 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/inner/data.ts @@ -0,0 +1,276 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { Demo03StudentApi } from '#/api/infra/demo/demo03/inner'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { getRangePickerDefaultProps } from '#/utils'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '名字', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入名字', + }, + }, + { + fieldName: 'sex', + label: '性别', + rules: 'required', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'), + buttonStyle: 'solid', + optionType: 'button', + }, + }, + { + fieldName: 'birthday', + label: '出生日期', + rules: 'required', + component: 'DatePicker', + componentProps: { + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + }, + }, + { + fieldName: 'description', + label: '简介', + rules: 'required', + component: 'RichTextarea', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '名字', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入名字', + }, + }, + { + fieldName: 'sex', + label: '性别', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'), + placeholder: '请选择性别', + }, + }, + { + fieldName: 'description', + label: '简介', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入简介', + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'DatePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { type: 'expand', width: 80, slots: { content: 'expand_content' } }, + { + field: 'id', + title: '编号', + minWidth: 120, + }, + { + field: 'name', + title: '名字', + minWidth: 120, + }, + { + field: 'sex', + title: '性别', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.SYSTEM_USER_SEX }, + }, + }, + { + field: 'birthday', + title: '出生日期', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + field: 'description', + title: '简介', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 280, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +// ==================== 子表(学生课程) ==================== + +/** 新增/修改列表的字段 */ +export function useDemo03CourseGridEditColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'name', + title: '名字', + minWidth: 120, + slots: { default: 'name' }, + }, + { + field: 'score', + title: '分数', + minWidth: 120, + slots: { default: 'score' }, + }, + { + title: '操作', + width: 280, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的字段 */ +export function useDemo03CourseGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '编号', + minWidth: 120, + }, + { + field: 'studentId', + title: '学生编号', + minWidth: 120, + }, + { + field: 'name', + title: '名字', + minWidth: 120, + }, + { + field: 'score', + title: '分数', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 120, + formatter: 'formatDateTime', + }, + ]; +} + +// ==================== 子表(学生班级) ==================== + +/** 新增/修改的表单 */ +export function useDemo03GradeFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '名字', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入名字', + }, + }, + { + fieldName: 'teacher', + label: '班主任', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入班主任', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useDemo03GradeGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '编号', + minWidth: 120, + }, + { + field: 'studentId', + title: '学生编号', + minWidth: 120, + }, + { + field: 'name', + title: '名字', + minWidth: 120, + }, + { + field: 'teacher', + title: '班主任', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 120, + formatter: 'formatDateTime', + }, + ]; +} diff --git a/apps/web-naive/src/views/infra/demo/demo03/inner/index.vue b/apps/web-naive/src/views/infra/demo/demo03/inner/index.vue new file mode 100644 index 000000000..059dd2a70 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/inner/index.vue @@ -0,0 +1,205 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-course-form.vue b/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-course-form.vue new file mode 100644 index 000000000..2be8932f9 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-course-form.vue @@ -0,0 +1,120 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-course-list.vue b/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-course-list.vue new file mode 100644 index 000000000..50297db48 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-course-list.vue @@ -0,0 +1,56 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-grade-form.vue b/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-grade-form.vue new file mode 100644 index 000000000..3e2854608 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-grade-form.vue @@ -0,0 +1,51 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-grade-list.vue b/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-grade-list.vue new file mode 100644 index 000000000..1ad2db740 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/inner/modules/demo03-grade-list.vue @@ -0,0 +1,56 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/inner/modules/form.vue b/apps/web-naive/src/views/infra/demo/demo03/inner/modules/form.vue new file mode 100644 index 000000000..fcc36caa3 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/inner/modules/form.vue @@ -0,0 +1,120 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/normal/data.ts b/apps/web-naive/src/views/infra/demo/demo03/normal/data.ts new file mode 100644 index 000000000..49200d435 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/normal/data.ts @@ -0,0 +1,211 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { Demo03StudentApi } from '#/api/infra/demo/demo03/normal'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { getRangePickerDefaultProps } from '#/utils'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '名字', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入名字', + }, + }, + { + fieldName: 'sex', + label: '性别', + rules: 'required', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'), + buttonStyle: 'solid', + optionType: 'button', + }, + }, + { + fieldName: 'birthday', + label: '出生日期', + rules: 'required', + component: 'DatePicker', + componentProps: { + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + }, + }, + { + fieldName: 'description', + label: '简介', + rules: 'required', + component: 'RichTextarea', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '名字', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入名字', + }, + }, + { + fieldName: 'sex', + label: '性别', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.SYSTEM_USER_SEX, 'number'), + placeholder: '请选择性别', + }, + }, + { + fieldName: 'description', + label: '简介', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入简介', + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'DatePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 40 }, + { + field: 'id', + title: '编号', + minWidth: 120, + }, + { + field: 'name', + title: '名字', + minWidth: 120, + }, + { + field: 'sex', + title: '性别', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.SYSTEM_USER_SEX }, + }, + }, + { + field: 'birthday', + title: '出生日期', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + field: 'description', + title: '简介', + minWidth: 120, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 120, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 200, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +// ==================== 子表(学生课程) ==================== + +/** 新增/修改列表的字段 */ +export function useDemo03CourseGridEditColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'name', + title: '名字', + minWidth: 120, + slots: { default: 'name' }, + }, + { + field: 'score', + title: '分数', + minWidth: 120, + slots: { default: 'score' }, + }, + { + title: '操作', + width: 200, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +// ==================== 子表(学生班级) ==================== + +/** 新增/修改的表单 */ +export function useDemo03GradeFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'name', + label: '名字', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入名字', + }, + }, + { + fieldName: 'teacher', + label: '班主任', + rules: 'required', + component: 'Input', + componentProps: { + placeholder: '请输入班主任', + }, + }, + ]; +} diff --git a/apps/web-naive/src/views/infra/demo/demo03/normal/index.vue b/apps/web-naive/src/views/infra/demo/demo03/normal/index.vue new file mode 100644 index 000000000..d21b0ccee --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/normal/index.vue @@ -0,0 +1,187 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/normal/modules/demo03-course-form.vue b/apps/web-naive/src/views/infra/demo/demo03/normal/modules/demo03-course-form.vue new file mode 100644 index 000000000..4d674cb99 --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/normal/modules/demo03-course-form.vue @@ -0,0 +1,119 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/normal/modules/demo03-grade-form.vue b/apps/web-naive/src/views/infra/demo/demo03/normal/modules/demo03-grade-form.vue new file mode 100644 index 000000000..5d5f396bf --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/normal/modules/demo03-grade-form.vue @@ -0,0 +1,51 @@ + + + diff --git a/apps/web-naive/src/views/infra/demo/demo03/normal/modules/form.vue b/apps/web-naive/src/views/infra/demo/demo03/normal/modules/form.vue new file mode 100644 index 000000000..624c941fa --- /dev/null +++ b/apps/web-naive/src/views/infra/demo/demo03/normal/modules/form.vue @@ -0,0 +1,120 @@ + + + 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..01ec58d5f --- /dev/null +++ b/apps/web-naive/src/views/infra/druid/index.vue @@ -0,0 +1,36 @@ + + +