Merge branch 'master' of https://gitee.com/yudaocode/yudao-ui-admin-vue3 into feature/iot

This commit is contained in:
YunaiV
2025-06-15 20:19:54 +08:00
37 changed files with 19072 additions and 422 deletions

View File

@@ -95,7 +95,20 @@
</el-table-column>
<el-table-column label="字典类型" min-width="12%">
<template #default="scope">
<el-select v-model="scope.row.dictType" clearable filterable placeholder="请选择">
<el-select v-model="scope.row.dictType" :value-on-clear="''" clearable filterable placeholder="请选择">
<template #header>
<div class="flex justify-end">
<el-popover
class="box-item"
content="加载最新字典"
placement="top-start"
>
<template #reference>
<el-button :icon="Refresh" size="small" circle @click="getDictOptions" class=""/>
</template>
</el-popover>
</div>
</template>
<el-option
v-for="dict in dictOptions"
:key="dict.id"
@@ -114,6 +127,7 @@
</template>
<script lang="ts" setup>
import { PropType } from 'vue'
import { Refresh } from '@element-plus/icons-vue'
import * as CodegenApi from '@/api/infra/codegen'
import * as DictDataApi from '@/api/system/dict/dict.type'

View File

@@ -15,7 +15,7 @@
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
:key="dict.value"
:value="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
@@ -44,7 +44,10 @@
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import * as Demo01ContactApi from '@/api/infra/demo/demo01'
import { Demo01ContactApi, Demo01Contact } from '@/api/infra/demo/demo01'
/** 示例联系人 表单 */
defineOptions({ name: 'Demo01ContactForm' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
@@ -59,13 +62,13 @@ const formData = ref({
sex: undefined,
birthday: undefined,
description: undefined,
avatar: undefined
avatar: undefined,
})
const formRules = reactive({
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
birthday: [{ required: true, message: '出生年不能为空', trigger: 'blur' }],
description: [{ required: true, message: '简介不能为空', trigger: 'blur' }]
description: [{ required: true, message: '简介不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
@@ -95,7 +98,7 @@ const submitForm = async () => {
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as Demo01ContactApi.Demo01ContactVO
const data = formData.value as unknown as Demo01Contact
if (formType.value === 'create') {
await Demo01ContactApi.createDemo01Contact(data)
message.success(t('common.createSuccess'))
@@ -119,7 +122,7 @@ const resetForm = () => {
sex: undefined,
birthday: undefined,
description: undefined,
avatar: undefined
avatar: undefined,
}
formRef.value?.resetFields()
}

View File

@@ -1,6 +1,4 @@
<template>
<doc-alert title="代码生成(单表)" url="https://doc.iocoder.cn/new-feature/" />
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
@@ -20,7 +18,12 @@
/>
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-select v-model="queryParams.sex" placeholder="请选择性别" clearable class="!w-240px">
<el-select
v-model="queryParams.sex"
placeholder="请选择性别"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
:key="dict.value"
@@ -37,7 +40,7 @@
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
class="!w-220px"
/>
</el-form-item>
<el-form-item>
@@ -60,13 +63,30 @@
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
<el-button
type="danger"
plain
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['infra:demo01-contact:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
@selection-change="handleRowCheckboxChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="名字" align="center" prop="name" />
<el-table-column label="性别" align="center" prop="sex">
@@ -90,7 +110,7 @@
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="操作" align="center">
<el-table-column label="操作" align="center" min-width="120px">
<template #default="scope">
<el-button
link
@@ -126,25 +146,27 @@
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { isEmpty } from '@/utils/is'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import * as Demo01ContactApi from '@/api/infra/demo/demo01'
import { Demo01ContactApi, Demo01Contact } from '@/api/infra/demo/demo01'
import Demo01ContactForm from './Demo01ContactForm.vue'
/** 示例联系人 列表 */
defineOptions({ name: 'Demo01Contact' })
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据
const list = ref<Demo01Contact[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: null,
sex: null,
createTime: []
name: undefined,
sex: undefined,
createTime: [],
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
@@ -192,6 +214,22 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除示例联系人 */
const handleDeleteBatch = async () => {
try {
// 删除的二次确认
await message.delConfirm()
await Demo01ContactApi.deleteDemo01ContactList(checkedIds.value);
message.success(t('common.delSuccess'))
await getList();
} catch {}
}
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (records: Demo01Contact[]) => {
checkedIds.value = records.map((item) => item.id);
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

View File

@@ -41,7 +41,10 @@
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/erp'
import { Demo03StudentApi, Demo03Student } from '@/api/infra/demo/demo03/erp'
/** 学生 表单 */
defineOptions({ name: 'Demo03StudentForm' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
@@ -55,13 +58,13 @@ const formData = ref({
name: undefined,
sex: undefined,
birthday: undefined,
description: undefined
description: undefined,
})
const formRules = reactive({
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
birthday: [{ required: true, message: '出生日期不能为空', trigger: 'blur' }],
description: [{ required: true, message: '简介不能为空', trigger: 'blur' }]
description: [{ required: true, message: '简介不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
@@ -91,7 +94,7 @@ const submitForm = async () => {
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as Demo03StudentApi.Demo03StudentVO
const data = formData.value as unknown as Demo03Student
if (formType.value === 'create') {
await Demo03StudentApi.createDemo03Student(data)
message.success(t('common.createSuccess'))
@@ -114,7 +117,7 @@ const resetForm = () => {
name: undefined,
sex: undefined,
birthday: undefined,
description: undefined
description: undefined,
}
formRef.value?.resetFields()
}

View File

@@ -7,7 +7,7 @@
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="名字" prop="name">
<el-form-item label="名字" prop="name">
<el-input v-model="formData.name" placeholder="请输入名字" />
</el-form-item>
<el-form-item label="分数" prop="score">
@@ -21,7 +21,7 @@
</Dialog>
</template>
<script setup lang="ts">
import * as Demo03StudentApi from '@/api/infra/demo/demo03/erp'
import { Demo03StudentApi, Demo03Course } from '@/api/infra/demo/demo03/erp'
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
@@ -34,22 +34,22 @@ const formData = ref({
id: undefined,
studentId: undefined,
name: undefined,
score: undefined
score: undefined,
})
const formRules = reactive({
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
score: [{ required: true, message: '分数不能为空', trigger: 'blur' }]
score: [{ required: true, message: '分数不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type: string, id?: number, studentId: number) => {
const open = async (type: string, id?: number, studentId?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
formData.value.studentId = studentId
formData.value.studentId = studentId as any
// 修改时,设置数据
if (id) {
formLoading.value = true
@@ -70,7 +70,7 @@ const submitForm = async () => {
// 提交请求
formLoading.value = true
try {
const data = formData.value
const data = formData.value as unknown as Demo03Course
if (formType.value === 'create') {
await Demo03StudentApi.createDemo03Course(data)
message.success(t('common.createSuccess'))
@@ -92,7 +92,7 @@ const resetForm = () => {
id: undefined,
studentId: undefined,
name: undefined,
score: undefined
score: undefined,
}
formRef.value?.resetFields()
}

View File

@@ -2,40 +2,56 @@
<!-- 列表 -->
<ContentWrap>
<el-button
v-hasPermi="['infra:demo03-student:create']"
plain
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['infra:demo03-student:create']"
>
<Icon class="mr-5px" icon="ep:plus" />
新增
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
<el-table-column align="center" label="编号" prop="id" />
<el-table-column align="center" label="名字" prop="name" />
<el-table-column align="center" label="分数" prop="score" />
<el-button
type="danger"
plain
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['infra:demo03-student:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
@selection-change="handleRowCheckboxChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="名字" align="center" prop="name" />
<el-table-column label="分数" align="center" prop="score" />
<el-table-column
:formatter="dateFormatter"
align="center"
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column align="center" label="操作">
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
v-hasPermi="['infra:demo03-student:update']"
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['infra:demo03-student:update']"
>
编辑
</el-button>
<el-button
v-hasPermi="['infra:demo03-student:delete']"
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['infra:demo03-student:delete']"
>
删除
</el-button>
@@ -44,19 +60,19 @@
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNo"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<Demo03CourseForm ref="formRef" @success="getList" />
<!-- 表单弹窗添加/修改 -->
<Demo03CourseForm ref="formRef" @success="getList" />
</template>
<script lang="ts" setup>
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/erp'
import { isEmpty } from '@/utils/is'
import {Demo03Course, Demo03StudentApi} from '@/api/infra/demo/demo03/erp'
import Demo03CourseForm from './Demo03CourseForm.vue'
const { t } = useI18n() // 国际化
@@ -84,7 +100,7 @@ watch(
queryParams.studentId = val
handleQuery()
},
{ immediate: true, deep: true }
{ immediate: true, deep: true }
)
/** 查询列表 */
@@ -127,4 +143,20 @@ const handleDelete = async (id: number) => {
await getList()
} catch {}
}
/** 批量删除学生课程 */
const handleDeleteBatch = async () => {
try {
// 删除的二次确认
await message.delConfirm()
await Demo03StudentApi.deleteDemo03CourseList(checkedIds.value);
message.success(t('common.delSuccess'))
await getList();
} catch {}
}
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (records: Demo03Course[]) => {
checkedIds.value = records.map((item) => item.id);
}
</script>

View File

@@ -7,7 +7,7 @@
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="名字" prop="name">
<el-form-item label="名字" prop="name">
<el-input v-model="formData.name" placeholder="请输入名字" />
</el-form-item>
<el-form-item label="班主任" prop="teacher">
@@ -21,7 +21,7 @@
</Dialog>
</template>
<script setup lang="ts">
import * as Demo03StudentApi from '@/api/infra/demo/demo03/erp'
import { Demo03StudentApi, Demo03Grade } from '@/api/infra/demo/demo03/erp'
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
@@ -34,22 +34,22 @@ const formData = ref({
id: undefined,
studentId: undefined,
name: undefined,
teacher: undefined
teacher: undefined,
})
const formRules = reactive({
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
teacher: [{ required: true, message: '班主任不能为空', trigger: 'blur' }]
teacher: [{ required: true, message: '班主任不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type: string, id?: number, studentId: number) => {
const open = async (type: string, id?: number, studentId?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
formData.value.studentId = studentId
formData.value.studentId = studentId as any
// 修改时,设置数据
if (id) {
formLoading.value = true
@@ -70,7 +70,7 @@ const submitForm = async () => {
// 提交请求
formLoading.value = true
try {
const data = formData.value
const data = formData.value as unknown as Demo03Grade
if (formType.value === 'create') {
await Demo03StudentApi.createDemo03Grade(data)
message.success(t('common.createSuccess'))
@@ -92,7 +92,7 @@ const resetForm = () => {
id: undefined,
studentId: undefined,
name: undefined,
teacher: undefined
teacher: undefined,
}
formRef.value?.resetFields()
}

View File

@@ -2,40 +2,56 @@
<!-- 列表 -->
<ContentWrap>
<el-button
v-hasPermi="['infra:demo03-student:create']"
plain
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['infra:demo03-student:create']"
>
<Icon class="mr-5px" icon="ep:plus" />
新增
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
<el-table-column align="center" label="编号" prop="id" />
<el-table-column align="center" label="名字" prop="name" />
<el-table-column align="center" label="班主任" prop="teacher" />
<el-button
type="danger"
plain
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['infra:demo03-student:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
@selection-change="handleRowCheckboxChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="名字" align="center" prop="name" />
<el-table-column label="班主任" align="center" prop="teacher" />
<el-table-column
:formatter="dateFormatter"
align="center"
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column align="center" label="操作">
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
v-hasPermi="['infra:demo03-student:update']"
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['infra:demo03-student:update']"
>
编辑
</el-button>
<el-button
v-hasPermi="['infra:demo03-student:delete']"
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['infra:demo03-student:delete']"
>
删除
</el-button>
@@ -44,19 +60,19 @@
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNo"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<Demo03GradeForm ref="formRef" @success="getList" />
<!-- 表单弹窗添加/修改 -->
<Demo03GradeForm ref="formRef" @success="getList" />
</template>
<script lang="ts" setup>
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/erp'
import { isEmpty } from '@/utils/is'
import {Demo03Grade, Demo03StudentApi} from '@/api/infra/demo/demo03/erp'
import Demo03GradeForm from './Demo03GradeForm.vue'
const { t } = useI18n() // 国际化
@@ -84,7 +100,7 @@ watch(
queryParams.studentId = val
handleQuery()
},
{ immediate: true, deep: true }
{ immediate: true, deep: true }
)
/** 查询列表 */
@@ -127,4 +143,20 @@ const handleDelete = async (id: number) => {
await getList()
} catch {}
}
/** 批量删除学生班级 */
const handleDeleteBatch = async () => {
try {
// 删除的二次确认
await message.delConfirm()
await Demo03StudentApi.deleteDemo03GradeList(checkedIds.value);
message.success(t('common.delSuccess'))
await getList();
} catch {}
}
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (records: Demo03Grade[]) => {
checkedIds.value = records.map((item) => item.id);
}
</script>

View File

@@ -1,26 +1,29 @@
<template>
<doc-alert title="代码生成(主子表)" url="https://doc.iocoder.cn/new-feature/master-sub/" />
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
:model="queryParams"
class="-mb-15px"
label-width="68px"
>
<el-form-item label="名字" prop="name">
<el-input
v-model="queryParams.name"
class="!w-240px"
clearable
placeholder="请输入名字"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-select v-model="queryParams.sex" class="!w-240px" clearable placeholder="请选择性别">
<el-select
v-model="queryParams.sex"
placeholder="请选择性别"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
:key="dict.value"
@@ -32,41 +35,42 @@
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
end-placeholder="结束日期"
start-placeholder="开始日期"
type="daterange"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-220px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery">
<Icon class="mr-5px" icon="ep:search" />
搜索
</el-button>
<el-button @click="resetQuery">
<Icon class="mr-5px" icon="ep:refresh" />
重置
</el-button>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
v-hasPermi="['infra:demo03-student:create']"
plain
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['infra:demo03-student:create']"
>
<Icon class="mr-5px" icon="ep:plus" />
新增
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
v-hasPermi="['infra:demo03-student:export']"
:loading="exportLoading"
plain
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['infra:demo03-student:export']"
>
<Icon class="mr-5px" icon="ep:download" />
导出
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
<el-button
type="danger"
plain
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['infra:demo03-student:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
@@ -75,50 +79,53 @@
<!-- 列表 -->
<ContentWrap>
<el-table
row-key="id"
v-loading="loading"
:data="list"
:show-overflow-tooltip="true"
:stripe="true"
:show-overflow-tooltip="true"
highlight-current-row
@current-change="handleCurrentChange"
@selection-change="handleRowCheckboxChange"
>
<el-table-column align="center" label="编号" prop="id" />
<el-table-column align="center" label="名字" prop="name" />
<el-table-column align="center" label="性别" prop="sex">
<el-table-column type="selection" width="55" />
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="名字" align="center" prop="name" />
<el-table-column label="性别" align="center" prop="sex">
<template #default="scope">
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
</template>
</el-table-column>
<el-table-column
:formatter="dateFormatter"
align="center"
label="出生日期"
prop="birthday"
width="180px"
/>
<el-table-column align="center" label="简介" prop="description" />
<el-table-column
:formatter="dateFormatter"
align="center"
label="创建时间"
prop="createTime"
prop="birthday"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column align="center" label="操作">
<el-table-column label="简介" align="center" prop="description" />
<el-table-column
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="操作" align="center" min-width="120px">
<template #default="scope">
<el-button
v-hasPermi="['infra:demo03-student:update']"
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['infra:demo03-student:update']"
>
编辑
</el-button>
<el-button
v-hasPermi="['infra:demo03-student:delete']"
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['infra:demo03-student:delete']"
>
删除
</el-button>
@@ -127,9 +134,9 @@
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNo"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
@@ -140,39 +147,41 @@
<ContentWrap>
<el-tabs model-value="demo03Course">
<el-tab-pane label="学生课程" name="demo03Course">
<Demo03CourseList :student-id="currentRow?.id" />
<Demo03CourseList :student-id="currentRow.id" />
</el-tab-pane>
<el-tab-pane label="学生班级" name="demo03Grade">
<Demo03GradeList :student-id="currentRow?.id" />
<Demo03GradeList :student-id="currentRow.id" />
</el-tab-pane>
</el-tabs>
</ContentWrap>
</template>
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { isEmpty } from '@/utils/is'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/erp'
import { Demo03StudentApi, Demo03Student } from '@/api/infra/demo/demo03/erp'
import Demo03StudentForm from './Demo03StudentForm.vue'
import Demo03CourseList from './components/Demo03CourseList.vue'
import Demo03GradeList from './components/Demo03GradeList.vue'
/** 学生 列表 */
defineOptions({ name: 'Demo03Student' })
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据
const list = ref<Demo03Student[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: null,
sex: null,
description: null,
createTime: []
name: undefined,
sex: undefined,
description: undefined,
createTime: [],
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
@@ -220,6 +229,22 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除学生 */
const handleDeleteBatch = async () => {
try {
// 删除的二次确认
await message.delConfirm()
await Demo03StudentApi.deleteDemo03StudentList(checkedIds.value);
message.success(t('common.delSuccess'))
await getList();
} catch {}
}
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (records: Demo03Student[]) => {
checkedIds.value = records.map((item) => item.id);
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

View File

@@ -49,11 +49,14 @@
</Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { Demo03Student, Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
import Demo03CourseForm from './components/Demo03CourseForm.vue'
import Demo03GradeForm from './components/Demo03GradeForm.vue'
/** 学生 表单 */
defineOptions({ name: 'Demo03StudentForm' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
@@ -120,7 +123,7 @@ const submitForm = async () => {
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as Demo03StudentApi.Demo03StudentVO
const data = formData.value as unknown as Demo03Student
// 拼接子表的数据
data.demo03Courses = demo03CourseFormRef.value.getData()
data.demo03Grade = demo03GradeFormRef.value.getData()

View File

@@ -35,13 +35,13 @@
</el-row>
</template>
<script setup lang="ts">
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
import { Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
const props = defineProps<{
studentId: undefined // 学生编号(主表的关联字段)
studentId: number // 学生编号(主表的关联字段)
}>()
const formLoading = ref(false) // 表单的加载中
const formData = ref([])
const formData = ref<any[]>([])
const formRules = reactive({
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
@@ -77,7 +77,7 @@ const handleAdd = () => {
name: undefined,
score: undefined
}
row.studentId = props.studentId
row.studentId = props.studentId as any
formData.value.push(row)
}

View File

@@ -1,7 +1,13 @@
<template>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
>
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="名字" align="center" prop="name" />
<el-table-column label="分数" align="center" prop="score" />
@@ -17,13 +23,10 @@
</template>
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
import { Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
const props = defineProps<{
studentId: undefined // 学生编号(主表的关联字段)
studentId?: number // 学生编号(主表的关联字段)
}>()
const loading = ref(false) // 列表的加载中
const list = ref([]) // 列表的数据
@@ -38,12 +41,6 @@ const getList = async () => {
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 初始化 **/
onMounted(() => {
getList()

View File

@@ -15,13 +15,13 @@
</el-form>
</template>
<script setup lang="ts">
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
import { Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
const props = defineProps<{
studentId: undefined // 学生编号(主表的关联字段)
studentId: number // 学生编号(主表的关联字段)
}>()
const formLoading = ref(false) // 表单的加载中
const formData = ref([])
const formData = ref<any>({})
const formRules = reactive({
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],

View File

@@ -1,7 +1,13 @@
<template>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
>
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="名字" align="center" prop="name" />
<el-table-column label="班主任" align="center" prop="teacher" />
@@ -17,13 +23,10 @@
</template>
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
import { Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
const props = defineProps<{
studentId: undefined // 学生编号(主表的关联字段)
studentId?: number // 学生编号(主表的关联字段)
}>()
const loading = ref(false) // 列表的加载中
const list = ref([]) // 列表的数据
@@ -42,12 +45,6 @@ const getList = async () => {
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 初始化 **/
onMounted(() => {
getList()

View File

@@ -1,6 +1,4 @@
<template>
<doc-alert title="代码生成(主子表)" url="https://doc.iocoder.cn/new-feature/master-sub/" />
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
@@ -37,7 +35,7 @@
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
class="!w-220px"
/>
</el-form-item>
<el-form-item>
@@ -60,13 +58,30 @@
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
<el-button
type="danger"
plain
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['infra:demo03-student:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
@selection-change="handleRowCheckboxChange"
>
<el-table-column type="selection" width="55" />
<!-- 子表的列表 -->
<el-table-column type="expand">
<template #default="scope">
@@ -102,7 +117,7 @@
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="操作" align="center">
<el-table-column label="操作" align="center" min-width="120px">
<template #default="scope">
<el-button
link
@@ -137,28 +152,30 @@
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { isEmpty } from '@/utils/is'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
import { Demo03Student, Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
import Demo03StudentForm from './Demo03StudentForm.vue'
import Demo03CourseList from './components/Demo03CourseList.vue'
import Demo03GradeList from './components/Demo03GradeList.vue'
/** 学生 列表 */
defineOptions({ name: 'Demo03Student' })
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据
const list = ref<Demo03Student[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: null,
sex: null,
description: null,
name: undefined,
sex: undefined,
description: undefined,
createTime: []
})
const queryFormRef = ref() // 搜索的表单
@@ -207,6 +224,22 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除学生 */
const handleDeleteBatch = async () => {
try {
// 删除的二次确认
await message.delConfirm()
await Demo03StudentApi.deleteDemo03StudentList(checkedIds.value)
message.success(t('common.delSuccess'))
await getList()
} catch {}
}
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (records: Demo03Student[]) => {
checkedIds.value = records.map((item) => item.id)
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

View File

@@ -50,10 +50,13 @@
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/normal'
import { Demo03StudentApi, Demo03Student } from '@/api/infra/demo/demo03/normal'
import Demo03CourseForm from './components/Demo03CourseForm.vue'
import Demo03GradeForm from './components/Demo03GradeForm.vue'
/** 学生 表单 */
defineOptions({ name: 'Demo03StudentForm' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
@@ -66,13 +69,13 @@ const formData = ref({
name: undefined,
sex: undefined,
birthday: undefined,
description: undefined
description: undefined,
})
const formRules = reactive({
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
birthday: [{ required: true, message: '出生日期不能为空', trigger: 'blur' }],
description: [{ required: true, message: '简介不能为空', trigger: 'blur' }]
description: [{ required: true, message: '简介不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
@@ -120,7 +123,7 @@ const submitForm = async () => {
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as Demo03StudentApi.Demo03StudentVO
const data = formData.value as unknown as Demo03Student
// 拼接子表的数据
data.demo03Courses = demo03CourseFormRef.value.getData()
data.demo03Grade = demo03GradeFormRef.value.getData()
@@ -146,7 +149,7 @@ const resetForm = () => {
name: undefined,
sex: undefined,
birthday: undefined,
description: undefined
description: undefined,
}
formRef.value?.resetFields()
}

View File

@@ -35,17 +35,17 @@
</el-row>
</template>
<script setup lang="ts">
import * as Demo03StudentApi from '@/api/infra/demo/demo03/normal'
import { Demo03StudentApi } from '@/api/infra/demo/demo03/normal'
const props = defineProps<{
studentId: undefined // 学生编号(主表的关联字段)
studentId: number // 学生编号(主表的关联字段)
}>()
const formLoading = ref(false) // 表单的加载中
const formData = ref([])
const formData = ref<any[]>([])
const formRules = reactive({
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
score: [{ required: true, message: '分数不能为空', trigger: 'blur' }]
score: [{ required: true, message: '分数不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
@@ -75,9 +75,9 @@ const handleAdd = () => {
id: undefined,
studentId: undefined,
name: undefined,
score: undefined
score: undefined,
}
row.studentId = props.studentId
row.studentId = props.studentId as any
formData.value.push(row)
}

View File

@@ -15,17 +15,17 @@
</el-form>
</template>
<script setup lang="ts">
import * as Demo03StudentApi from '@/api/infra/demo/demo03/normal'
import { Demo03StudentApi } from '@/api/infra/demo/demo03/normal'
const props = defineProps<{
studentId: undefined // 学生编号(主表的关联字段)
studentId: number // 学生编号(主表的关联字段)
}>()
const formLoading = ref(false) // 表单的加载中
const formData = ref([])
const formData = ref({})
const formRules = reactive({
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
teacher: [{ required: true, message: '班主任不能为空', trigger: 'blur' }]
teacher: [{ required: true, message: '班主任不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref

View File

@@ -1,6 +1,4 @@
<template>
<doc-alert title="代码生成(主子表)" url="https://doc.iocoder.cn/new-feature/master-sub/" />
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
@@ -20,7 +18,12 @@
/>
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-select v-model="queryParams.sex" placeholder="请选择性别" clearable class="!w-240px">
<el-select
v-model="queryParams.sex"
placeholder="请选择性别"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
:key="dict.value"
@@ -37,7 +40,7 @@
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
class="!w-220px"
/>
</el-form-item>
<el-form-item>
@@ -60,13 +63,30 @@
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
<el-button
type="danger"
plain
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['infra:demo03-student:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
@selection-change="handleRowCheckboxChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="名字" align="center" prop="name" />
<el-table-column label="性别" align="center" prop="sex">
@@ -89,7 +109,7 @@
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="操作" align="center">
<el-table-column label="操作" align="center" min-width="120px">
<template #default="scope">
<el-button
link
@@ -125,26 +145,28 @@
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { isEmpty } from '@/utils/is'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/normal'
import { Demo03StudentApi, Demo03Student } from '@/api/infra/demo/demo03/normal'
import Demo03StudentForm from './Demo03StudentForm.vue'
/** 学生 列表 */
defineOptions({ name: 'Demo03Student' })
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据
const list = ref<Demo03Student[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: null,
sex: null,
description: null,
createTime: []
name: undefined,
sex: undefined,
description: undefined,
createTime: [],
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
@@ -192,6 +214,22 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除学生 */
const handleDeleteBatch = async () => {
try {
// 删除的二次确认
await message.delConfirm()
await Demo03StudentApi.deleteDemo03StudentList(checkedIds.value);
message.success(t('common.delSuccess'))
await getList();
} catch {}
}
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (records: Demo03Student[]) => {
checkedIds.value = records.map((item) => item.id);
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

View File

@@ -46,8 +46,24 @@ const filterNode = (name: string, data: Tree) => {
}
/** 处理部门被点击 */
const handleNodeClick = async (row: { [key: string]: any }) => {
emits('node-click', row)
let currentNode: any = {}
const handleNodeClick = async (row: { [key: string]: any }, treeNode: any) => {
// 判断选中状态
if (currentNode && currentNode.name === row.name) {
treeNode.checked = !treeNode.checked
} else {
treeNode.checked = true
}
if (treeNode.checked) {
// 选中
currentNode = row
emits('node-click', row)
} else {
// 取消选中
treeRef.value!.setCurrentKey(undefined)
emits('node-click', undefined)
currentNode = null
}
}
const emits = defineEmits(['node-click'])

View File

@@ -255,9 +255,14 @@ const resetQuery = () => {
}
/** 处理部门被点击 */
const handleDeptNodeClick = async (row) => {
queryParams.deptId = row.id
await getList()
const handleDeptNodeClick = async (row: any) => {
if (row === undefined) {
queryParams.deptId = undefined
await getList()
} else {
queryParams.deptId = row.id
await getList()
}
}
/** 添加/修改操作 */