diff --git a/.eslintrc.js b/.eslintrc.js
index f2977df6..70c91784 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -21,7 +21,7 @@ module.exports = defineConfig({
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
- 'plugin:prettier/recommended',
+ 'plugin:prettier/recommended',
'@unocss'
],
rules: {
@@ -67,6 +67,7 @@ module.exports = defineConfig({
}
],
'vue/multi-word-component-names': 'off',
- 'vue/no-v-html': 'off'
+ 'vue/no-v-html': 'off',
+ 'prettier/prettier': 'off' // 芋艿:默认关闭 prettier 的 ESLint 校验,因为我们使用的是 IDE 的 Prettier 插件
}
})
diff --git a/src/api/infra/codegen/index.ts b/src/api/infra/codegen/index.ts
index 64701efe..1b91e917 100644
--- a/src/api/infra/codegen/index.ts
+++ b/src/api/infra/codegen/index.ts
@@ -67,6 +67,11 @@ export type CodegenCreateListReqVO = {
tableNames: string[]
}
+// 查询列表代码生成表定义
+export const getCodegenTableList = (dataSourceConfigId: number) => {
+ return request.get({ url: '/infra/codegen/table/list?dataSourceConfigId=' + dataSourceConfigId })
+}
+
// 查询列表代码生成表定义
export const getCodegenTablePage = (params: PageParam) => {
return request.get({ url: '/infra/codegen/table/page', params })
@@ -92,11 +97,6 @@ export const syncCodegenFromDB = (id: number) => {
return request.put({ url: '/infra/codegen/sync-from-db?tableId=' + id })
}
-// 基于 SQL 建表语句,同步数据库的表和字段定义
-export const syncCodegenFromSQL = (id: number, sql: string) => {
- return request.put({ url: '/infra/codegen/sync-from-sql?tableId=' + id + '&sql=' + sql })
-}
-
// 预览生成代码
export const previewCodegen = (id: number) => {
return request.get({ url: '/infra/codegen/preview?tableId=' + id })
diff --git a/src/api/infra/demo/demo01/index.ts b/src/api/infra/demo/demo01/index.ts
new file mode 100644
index 00000000..1a4b01ca
--- /dev/null
+++ b/src/api/infra/demo/demo01/index.ts
@@ -0,0 +1,40 @@
+import request from '@/config/axios'
+
+export interface Demo01ContactVO {
+ id: number
+ name: string
+ sex: number
+ birthday: Date
+ description: string
+ avatar: string
+}
+
+// 查询示例联系人分页
+export const getDemo01ContactPage = async (params) => {
+ return await request.get({ url: `/infra/demo01-contact/page`, params })
+}
+
+// 查询示例联系人详情
+export const getDemo01Contact = async (id: number) => {
+ return await request.get({ url: `/infra/demo01-contact/get?id=` + id })
+}
+
+// 新增示例联系人
+export const createDemo01Contact = async (data: Demo01ContactVO) => {
+ return await request.post({ url: `/infra/demo01-contact/create`, data })
+}
+
+// 修改示例联系人
+export const updateDemo01Contact = async (data: Demo01ContactVO) => {
+ return await request.put({ url: `/infra/demo01-contact/update`, data })
+}
+
+// 删除示例联系人
+export const deleteDemo01Contact = async (id: number) => {
+ return await request.delete({ url: `/infra/demo01-contact/delete?id=` + id })
+}
+
+// 导出示例联系人 Excel
+export const exportDemo01Contact = async (params) => {
+ return await request.download({ url: `/infra/demo01-contact/export-excel`, params })
+}
\ No newline at end of file
diff --git a/src/api/infra/demo/demo02/index.ts b/src/api/infra/demo/demo02/index.ts
new file mode 100644
index 00000000..21e45c90
--- /dev/null
+++ b/src/api/infra/demo/demo02/index.ts
@@ -0,0 +1,37 @@
+import request from '@/config/axios'
+
+export interface Demo02CategoryVO {
+ id: number
+ name: string
+ parentId: number
+}
+
+// 查询示例分类列表
+export const getDemo02CategoryList = async (params) => {
+ return await request.get({ url: `/infra/demo02-category/list`, params })
+}
+
+// 查询示例分类详情
+export const getDemo02Category = async (id: number) => {
+ return await request.get({ url: `/infra/demo02-category/get?id=` + id })
+}
+
+// 新增示例分类
+export const createDemo02Category = async (data: Demo02CategoryVO) => {
+ return await request.post({ url: `/infra/demo02-category/create`, data })
+}
+
+// 修改示例分类
+export const updateDemo02Category = async (data: Demo02CategoryVO) => {
+ return await request.put({ url: `/infra/demo02-category/update`, data })
+}
+
+// 删除示例分类
+export const deleteDemo02Category = async (id: number) => {
+ return await request.delete({ url: `/infra/demo02-category/delete?id=` + id })
+}
+
+// 导出示例分类 Excel
+export const exportDemo02Category = async (params) => {
+ return await request.download({ url: `/infra/demo02-category/export-excel`, params })
+}
\ No newline at end of file
diff --git a/src/api/infra/demo/demo03/erp/index.ts b/src/api/infra/demo/demo03/erp/index.ts
new file mode 100644
index 00000000..d408b630
--- /dev/null
+++ b/src/api/infra/demo/demo03/erp/index.ts
@@ -0,0 +1,91 @@
+import request from '@/config/axios'
+
+export interface Demo03StudentVO {
+ id: number
+ name: string
+ sex: number
+ birthday: Date
+ description: string
+}
+
+// 查询学生分页
+export const getDemo03StudentPage = async (params) => {
+ return await request.get({ url: `/infra/demo03-student/page`, params })
+}
+
+// 查询学生详情
+export const getDemo03Student = async (id: number) => {
+ return await request.get({ url: `/infra/demo03-student/get?id=` + id })
+}
+
+// 新增学生
+export const createDemo03Student = async (data: Demo03StudentVO) => {
+ return await request.post({ url: `/infra/demo03-student/create`, data })
+}
+
+// 修改学生
+export const updateDemo03Student = async (data: Demo03StudentVO) => {
+ return await request.put({ url: `/infra/demo03-student/update`, data })
+}
+
+// 删除学生
+export const deleteDemo03Student = async (id: number) => {
+ return await request.delete({ url: `/infra/demo03-student/delete?id=` + id })
+}
+
+// 导出学生 Excel
+export const exportDemo03Student = async (params) => {
+ return await request.download({ url: `/infra/demo03-student/export-excel`, params })
+}
+
+// ==================== 子表(学生课程) ====================
+
+// 获得学生课程分页
+export const getDemo03CoursePage = async (params) => {
+ return await request.get({ url: `/infra/demo03-student/demo03-course/page`, params })
+}
+// 新增学生课程
+export const createDemo03Course = async (data) => {
+ return await request.post({ url: `/infra/demo03-student/demo03-course/create`, data })
+}
+
+// 修改学生课程
+export const updateDemo03Course = async (data) => {
+ return await request.put({ url: `/infra/demo03-student/demo03-course/update`, data })
+}
+
+// 删除学生课程
+export const deleteDemo03Course = async (id: number) => {
+ return await request.delete({ url: `/infra/demo03-student/demo03-course/delete?id=` + id })
+}
+
+// 获得学生课程
+export const getDemo03Course = async (id: number) => {
+ return await request.get({ url: `/infra/demo03-student/demo03-course/get?id=` + id })
+}
+
+// ==================== 子表(学生班级) ====================
+
+// 获得学生班级分页
+export const getDemo03GradePage = async (params) => {
+ return await request.get({ url: `/infra/demo03-student/demo03-grade/page`, params })
+}
+// 新增学生班级
+export const createDemo03Grade = async (data) => {
+ return await request.post({ url: `/infra/demo03-student/demo03-grade/create`, data })
+}
+
+// 修改学生班级
+export const updateDemo03Grade = async (data) => {
+ return await request.put({ url: `/infra/demo03-student/demo03-grade/update`, data })
+}
+
+// 删除学生班级
+export const deleteDemo03Grade = async (id: number) => {
+ return await request.delete({ url: `/infra/demo03-student/demo03-grade/delete?id=` + id })
+}
+
+// 获得学生班级
+export const getDemo03Grade = async (id: number) => {
+ return await request.get({ url: `/infra/demo03-student/demo03-grade/get?id=` + id })
+}
\ No newline at end of file
diff --git a/src/api/infra/demo/demo03/inner/index.ts b/src/api/infra/demo/demo03/inner/index.ts
new file mode 100644
index 00000000..f15ee1dc
--- /dev/null
+++ b/src/api/infra/demo/demo03/inner/index.ts
@@ -0,0 +1,53 @@
+import request from '@/config/axios'
+
+export interface Demo03StudentVO {
+ id: number
+ name: string
+ sex: number
+ birthday: Date
+ description: string
+}
+
+// 查询学生分页
+export const getDemo03StudentPage = async (params) => {
+ return await request.get({ url: `/infra/demo03-student/page`, params })
+}
+
+// 查询学生详情
+export const getDemo03Student = async (id: number) => {
+ return await request.get({ url: `/infra/demo03-student/get?id=` + id })
+}
+
+// 新增学生
+export const createDemo03Student = async (data: Demo03StudentVO) => {
+ return await request.post({ url: `/infra/demo03-student/create`, data })
+}
+
+// 修改学生
+export const updateDemo03Student = async (data: Demo03StudentVO) => {
+ return await request.put({ url: `/infra/demo03-student/update`, data })
+}
+
+// 删除学生
+export const deleteDemo03Student = async (id: number) => {
+ return await request.delete({ url: `/infra/demo03-student/delete?id=` + id })
+}
+
+// 导出学生 Excel
+export const exportDemo03Student = async (params) => {
+ return await request.download({ url: `/infra/demo03-student/export-excel`, params })
+}
+
+// ==================== 子表(学生课程) ====================
+
+// 获得学生课程列表
+export const getDemo03CourseListByStudentId = async (studentId) => {
+ return await request.get({ url: `/infra/demo03-student/demo03-course/list-by-student-id?studentId=` + studentId })
+}
+
+// ==================== 子表(学生班级) ====================
+
+// 获得学生班级
+export const getDemo03GradeByStudentId = async (studentId) => {
+ return await request.get({ url: `/infra/demo03-student/demo03-grade/get-by-student-id?studentId=` + studentId })
+}
\ No newline at end of file
diff --git a/src/api/infra/demo/demo03/normal/index.ts b/src/api/infra/demo/demo03/normal/index.ts
new file mode 100644
index 00000000..f15ee1dc
--- /dev/null
+++ b/src/api/infra/demo/demo03/normal/index.ts
@@ -0,0 +1,53 @@
+import request from '@/config/axios'
+
+export interface Demo03StudentVO {
+ id: number
+ name: string
+ sex: number
+ birthday: Date
+ description: string
+}
+
+// 查询学生分页
+export const getDemo03StudentPage = async (params) => {
+ return await request.get({ url: `/infra/demo03-student/page`, params })
+}
+
+// 查询学生详情
+export const getDemo03Student = async (id: number) => {
+ return await request.get({ url: `/infra/demo03-student/get?id=` + id })
+}
+
+// 新增学生
+export const createDemo03Student = async (data: Demo03StudentVO) => {
+ return await request.post({ url: `/infra/demo03-student/create`, data })
+}
+
+// 修改学生
+export const updateDemo03Student = async (data: Demo03StudentVO) => {
+ return await request.put({ url: `/infra/demo03-student/update`, data })
+}
+
+// 删除学生
+export const deleteDemo03Student = async (id: number) => {
+ return await request.delete({ url: `/infra/demo03-student/delete?id=` + id })
+}
+
+// 导出学生 Excel
+export const exportDemo03Student = async (params) => {
+ return await request.download({ url: `/infra/demo03-student/export-excel`, params })
+}
+
+// ==================== 子表(学生课程) ====================
+
+// 获得学生课程列表
+export const getDemo03CourseListByStudentId = async (studentId) => {
+ return await request.get({ url: `/infra/demo03-student/demo03-course/list-by-student-id?studentId=` + studentId })
+}
+
+// ==================== 子表(学生班级) ====================
+
+// 获得学生班级
+export const getDemo03GradeByStudentId = async (studentId) => {
+ return await request.get({ url: `/infra/demo03-student/demo03-grade/get-by-student-id?studentId=` + studentId })
+}
\ No newline at end of file
diff --git a/src/components/UploadFile/src/UploadFile.vue b/src/components/UploadFile/src/UploadFile.vue
index 6895440b..c1f3e4e2 100644
--- a/src/components/UploadFile/src/UploadFile.vue
+++ b/src/components/UploadFile/src/UploadFile.vue
@@ -144,6 +144,8 @@ watch(
} else if (isArray(props.modelValue)) {
// 情况2:字符串
files.concat(props.modelValue)
+ } else if (props.modelValue == null) {
+ // 情况3:undefined 不处理
} else {
throw new Error('不支持的 modelValue 类型')
}
diff --git a/src/views/infra/codegen/EditTable.vue b/src/views/infra/codegen/EditTable.vue
index 9c4e7657..c94e0da6 100644
--- a/src/views/infra/codegen/EditTable.vue
+++ b/src/views/infra/codegen/EditTable.vue
@@ -8,7 +8,7 @@
-
+
diff --git a/src/views/infra/codegen/components/GenerateInfoForm.vue b/src/views/infra/codegen/components/GenerateInfoForm.vue
index 744edfe6..d2a01cc0 100644
--- a/src/views/infra/codegen/components/GenerateInfoForm.vue
+++ b/src/views/infra/codegen/components/GenerateInfoForm.vue
@@ -3,7 +3,7 @@
-
+
-
-
-
-
-
-
- 树编码字段
-
-
-
-
-
-
-
-
-
+
+
+
+
-
+
- 树父编码字段
+ 父编号字段
-
+
-
+
树名称字段
@@ -234,60 +217,79 @@
-
-
+
-
-
+
+
+
+
+
+
-
+
- 关联子表的表名
-
+ 关联的主表
+
-
+
-
+
- 子表关联的外键名
-
+ 子表关联的字段
+
-
+
+
+
+
+
+ 关联关系
+
+
+
+
+
+
+ 一对多
+ 一对一
+
+
+
@@ -305,6 +307,10 @@ const props = defineProps({
table: {
type: Object as PropType>,
default: () => null
+ },
+ columns: {
+ type: Array as unknown as PropType,
+ default: () => null
}
})
@@ -319,13 +325,12 @@ const formData = ref({
classComment: '',
parentMenuId: null,
genPath: '',
- treeCode: '',
- treeParentCode: '',
- treeName: '',
- tplCategory: '',
- subTableName: '',
- subTableFkName: '',
- genType: ''
+ genType: '',
+ masterTableId: undefined,
+ subJoinColumnId: undefined,
+ subJoinMany: undefined,
+ treeParentColumnId: undefined,
+ treeNameColumnId: undefined
})
const rules = reactive({
@@ -336,41 +341,29 @@ const rules = reactive({
businessName: [required],
businessPackage: [required],
className: [required],
- classComment: [required]
+ classComment: [required],
+ masterTableId: [required],
+ subJoinColumnId: [required],
+ subJoinMany: [required],
+ treeParentColumnId: [required],
+ treeNameColumnId: [required]
})
-const tables = ref([])
-const subColumns = ref([])
+const tables = ref([]) // 表定义列表
const menus = ref([])
const menuTreeProps = {
label: 'name'
}
-/** 选择子表名触发 */
-const subSelectChange = () => {
- formData.value.subTableFkName = ''
-}
-
-/** 选择生成模板触发 */
-const tplSelectChange = (value) => {
- if (value !== 1) {
- // TODO 芋艿:暂时不考虑支持树形结构
- message.error(
- '暂时不考虑支持【树形】和【主子表】的代码生成。原因是:导致 vm 模板过于复杂,不利于胖友二次开发'
- )
- return false
- }
- if (value !== 'sub') {
- formData.value.subTableName = ''
- formData.value.subTableFkName = ''
- }
-}
-
watch(
() => props.table,
- (table) => {
+ async (table) => {
if (!table) return
formData.value = table as any
+ // 加载表列表
+ if (table.dataSourceConfigId >= 0) {
+ tables.value = await CodegenApi.getCodegenTableList(formData.value.dataSourceConfigId)
+ }
},
{
deep: true,
@@ -380,6 +373,7 @@ watch(
onMounted(async () => {
try {
+ // 加载菜单
const resp = await MenuApi.getSimpleMenusList()
menus.value = handleTree(resp)
} catch {}
diff --git a/src/views/infra/demo/demo01/Demo01ContactForm.vue b/src/views/infra/demo/demo01/Demo01ContactForm.vue
new file mode 100644
index 00000000..0452a3c0
--- /dev/null
+++ b/src/views/infra/demo/demo01/Demo01ContactForm.vue
@@ -0,0 +1,126 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo01/index.vue b/src/views/infra/demo/demo01/index.vue
new file mode 100644
index 00000000..55751e1b
--- /dev/null
+++ b/src/views/infra/demo/demo01/index.vue
@@ -0,0 +1,217 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo02/Demo02CategoryForm.vue b/src/views/infra/demo/demo02/Demo02CategoryForm.vue
new file mode 100644
index 00000000..9002d5ee
--- /dev/null
+++ b/src/views/infra/demo/demo02/Demo02CategoryForm.vue
@@ -0,0 +1,114 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo02/index.vue b/src/views/infra/demo/demo02/index.vue
new file mode 100644
index 00000000..e46c77dc
--- /dev/null
+++ b/src/views/infra/demo/demo02/index.vue
@@ -0,0 +1,205 @@
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+ 导出
+
+
+ 展开/折叠
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/erp/Demo03StudentForm.vue b/src/views/infra/demo/demo03/erp/Demo03StudentForm.vue
new file mode 100644
index 00000000..29f1370d
--- /dev/null
+++ b/src/views/infra/demo/demo03/erp/Demo03StudentForm.vue
@@ -0,0 +1,121 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/erp/components/Demo03CourseForm.vue b/src/views/infra/demo/demo03/erp/components/Demo03CourseForm.vue
new file mode 100644
index 00000000..de1c06de
--- /dev/null
+++ b/src/views/infra/demo/demo03/erp/components/Demo03CourseForm.vue
@@ -0,0 +1,99 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/erp/components/Demo03CourseList.vue b/src/views/infra/demo/demo03/erp/components/Demo03CourseList.vue
new file mode 100644
index 00000000..7e06ee64
--- /dev/null
+++ b/src/views/infra/demo/demo03/erp/components/Demo03CourseList.vue
@@ -0,0 +1,126 @@
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/erp/components/Demo03GradeForm.vue b/src/views/infra/demo/demo03/erp/components/Demo03GradeForm.vue
new file mode 100644
index 00000000..abba0032
--- /dev/null
+++ b/src/views/infra/demo/demo03/erp/components/Demo03GradeForm.vue
@@ -0,0 +1,99 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/erp/components/Demo03GradeList.vue b/src/views/infra/demo/demo03/erp/components/Demo03GradeList.vue
new file mode 100644
index 00000000..b12f1889
--- /dev/null
+++ b/src/views/infra/demo/demo03/erp/components/Demo03GradeList.vue
@@ -0,0 +1,126 @@
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/erp/index.vue b/src/views/infra/demo/demo03/erp/index.vue
new file mode 100644
index 00000000..8fdc7b42
--- /dev/null
+++ b/src/views/infra/demo/demo03/erp/index.vue
@@ -0,0 +1,243 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/inner/Demo03StudentForm.vue b/src/views/infra/demo/demo03/inner/Demo03StudentForm.vue
new file mode 100644
index 00000000..fe9327b9
--- /dev/null
+++ b/src/views/infra/demo/demo03/inner/Demo03StudentForm.vue
@@ -0,0 +1,153 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/inner/components/Demo03CourseForm.vue b/src/views/infra/demo/demo03/inner/components/Demo03CourseForm.vue
new file mode 100644
index 00000000..87057513
--- /dev/null
+++ b/src/views/infra/demo/demo03/inner/components/Demo03CourseForm.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ —
+
+
+
+
+
+ + 添加学生课程
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/inner/components/Demo03CourseList.vue b/src/views/infra/demo/demo03/inner/components/Demo03CourseList.vue
new file mode 100644
index 00000000..d912fc5d
--- /dev/null
+++ b/src/views/infra/demo/demo03/inner/components/Demo03CourseList.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/inner/components/Demo03GradeForm.vue b/src/views/infra/demo/demo03/inner/components/Demo03GradeForm.vue
new file mode 100644
index 00000000..e0eeb192
--- /dev/null
+++ b/src/views/infra/demo/demo03/inner/components/Demo03GradeForm.vue
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/inner/components/Demo03GradeList.vue b/src/views/infra/demo/demo03/inner/components/Demo03GradeList.vue
new file mode 100644
index 00000000..96905414
--- /dev/null
+++ b/src/views/infra/demo/demo03/inner/components/Demo03GradeList.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/inner/index.vue b/src/views/infra/demo/demo03/inner/index.vue
new file mode 100644
index 00000000..4ce6037d
--- /dev/null
+++ b/src/views/infra/demo/demo03/inner/index.vue
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/normal/Demo03StudentForm.vue b/src/views/infra/demo/demo03/normal/Demo03StudentForm.vue
new file mode 100644
index 00000000..00508228
--- /dev/null
+++ b/src/views/infra/demo/demo03/normal/Demo03StudentForm.vue
@@ -0,0 +1,153 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/normal/components/Demo03CourseForm.vue b/src/views/infra/demo/demo03/normal/components/Demo03CourseForm.vue
new file mode 100644
index 00000000..b6f58572
--- /dev/null
+++ b/src/views/infra/demo/demo03/normal/components/Demo03CourseForm.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ —
+
+
+
+
+
+ + 添加学生课程
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/normal/components/Demo03GradeForm.vue b/src/views/infra/demo/demo03/normal/components/Demo03GradeForm.vue
new file mode 100644
index 00000000..12653b6c
--- /dev/null
+++ b/src/views/infra/demo/demo03/normal/components/Demo03GradeForm.vue
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/demo/demo03/normal/index.vue b/src/views/infra/demo/demo03/normal/index.vue
new file mode 100644
index 00000000..52029107
--- /dev/null
+++ b/src/views/infra/demo/demo03/normal/index.vue
@@ -0,0 +1,217 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/infra/testDemo/index.vue b/src/views/infra/testDemo/index.vue
deleted file mode 100644
index ca6a5b07..00000000
--- a/src/views/infra/testDemo/index.vue
+++ /dev/null
@@ -1,4 +0,0 @@
-
- index
-
-