Merge branch 'master' of https://gitee.com/yudaocode/yudao-ui-admin-vue3 into feature/iot
commit
259f437ea4
|
|
@ -62,16 +62,16 @@
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"[typescript]": {
|
"[typescript]": {
|
||||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"[typescriptreact]": {
|
"[typescriptreact]": {
|
||||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"[html]": {
|
"[html]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"[css]": {
|
"[css]": {
|
||||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"[less]": {
|
"[less]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
|
@ -86,8 +86,9 @@
|
||||||
"source.fixAll.eslint": "explicit",
|
"source.fixAll.eslint": "explicit",
|
||||||
"source.fixAll.stylelint": "explicit"
|
"source.fixAll.stylelint": "explicit"
|
||||||
},
|
},
|
||||||
|
"editor.formatOnSave": true,
|
||||||
"[vue]": {
|
"[vue]": {
|
||||||
"editor.defaultFormatter": "octref.vetur"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"i18n-ally.localesPaths": ["src/locales"],
|
"i18n-ally.localesPaths": ["src/locales"],
|
||||||
"i18n-ally.keystyle": "nested",
|
"i18n-ally.keystyle": "nested",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -36,7 +36,7 @@
|
||||||
"@wangeditor/editor-for-vue": "^5.1.10",
|
"@wangeditor/editor-for-vue": "^5.1.10",
|
||||||
"@zxcvbn-ts/core": "^3.0.4",
|
"@zxcvbn-ts/core": "^3.0.4",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"axios": "^1.6.8",
|
"axios": "1.9.0",
|
||||||
"benz-amr-recorder": "^1.1.5",
|
"benz-amr-recorder": "^1.1.5",
|
||||||
"bpmn-js-token-simulation": "^0.36.0",
|
"bpmn-js-token-simulation": "^0.36.0",
|
||||||
"camunda-bpmn-moddle": "^7.0.1",
|
"camunda-bpmn-moddle": "^7.0.1",
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,50 @@
|
||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
import type { Dayjs } from 'dayjs'
|
||||||
|
|
||||||
export interface Demo01ContactVO {
|
/** 示例联系人信息 */
|
||||||
id: number
|
export interface Demo01Contact {
|
||||||
name: string
|
id: number // 编号
|
||||||
sex: number
|
name?: string // 名字
|
||||||
birthday: Date
|
sex?: number // 性别
|
||||||
description: string
|
birthday?: string | Dayjs // 出生年
|
||||||
avatar: string
|
description?: string // 简介
|
||||||
|
avatar: string // 头像
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询示例联系人分页
|
// 示例联系人 API
|
||||||
export const getDemo01ContactPage = async (params) => {
|
export const Demo01ContactApi = {
|
||||||
return await request.get({ url: `/infra/demo01-contact/page`, params })
|
// 查询示例联系人分页
|
||||||
}
|
getDemo01ContactPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/infra/demo01-contact/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
// 查询示例联系人详情
|
// 查询示例联系人详情
|
||||||
export const getDemo01Contact = async (id: number) => {
|
getDemo01Contact: async (id: number) => {
|
||||||
return await request.get({ url: `/infra/demo01-contact/get?id=` + id })
|
return await request.get({ url: `/infra/demo01-contact/get?id=` + id })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 新增示例联系人
|
// 新增示例联系人
|
||||||
export const createDemo01Contact = async (data: Demo01ContactVO) => {
|
createDemo01Contact: async (data: Demo01Contact) => {
|
||||||
return await request.post({ url: `/infra/demo01-contact/create`, data })
|
return await request.post({ url: `/infra/demo01-contact/create`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 修改示例联系人
|
// 修改示例联系人
|
||||||
export const updateDemo01Contact = async (data: Demo01ContactVO) => {
|
updateDemo01Contact: async (data: Demo01Contact) => {
|
||||||
return await request.put({ url: `/infra/demo01-contact/update`, data })
|
return await request.put({ url: `/infra/demo01-contact/update`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 删除示例联系人
|
// 删除示例联系人
|
||||||
export const deleteDemo01Contact = async (id: number) => {
|
deleteDemo01Contact: async (id: number) => {
|
||||||
return await request.delete({ url: `/infra/demo01-contact/delete?id=` + id })
|
return await request.delete({ url: `/infra/demo01-contact/delete?id=` + id })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 导出示例联系人 Excel
|
/** 批量删除示例联系人 */
|
||||||
export const exportDemo01Contact = async (params) => {
|
deleteDemo01ContactList: async (ids: number[]) => {
|
||||||
return await request.download({ url: `/infra/demo01-contact/export-excel`, params })
|
return await request.delete({ url: `/infra/demo01-contact/delete-list?ids=${ids.join(',')}` })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出示例联系人 Excel
|
||||||
|
exportDemo01Contact: async (params) => {
|
||||||
|
return await request.download({ url: `/infra/demo01-contact/export-excel`, params })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,91 +1,127 @@
|
||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
import type { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
export interface Demo03StudentVO {
|
/** 学生课程信息 */
|
||||||
id: number
|
export interface Demo03Course {
|
||||||
name: string
|
id: number; // 编号
|
||||||
sex: number
|
studentId?: number; // 学生编号
|
||||||
birthday: Date
|
name?: string; // 名字
|
||||||
description: string
|
score?: number; // 分数
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询学生分页
|
/** 学生班级信息 */
|
||||||
export const getDemo03StudentPage = async (params) => {
|
export interface Demo03Grade {
|
||||||
return await request.get({ url: `/infra/demo03-student/page`, params })
|
id: number; // 编号
|
||||||
|
studentId?: number; // 学生编号
|
||||||
|
name?: string; // 名字
|
||||||
|
teacher?: string; // 班主任
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询学生详情
|
/** 学生信息 */
|
||||||
export const getDemo03Student = async (id: number) => {
|
export interface Demo03Student {
|
||||||
return await request.get({ url: `/infra/demo03-student/get?id=` + id })
|
id: number; // 编号
|
||||||
|
name?: string; // 名字
|
||||||
|
sex?: number; // 性别
|
||||||
|
birthday?: string | Dayjs; // 出生日期
|
||||||
|
description?: string; // 简介
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增学生
|
// 学生 API
|
||||||
export const createDemo03Student = async (data: Demo03StudentVO) => {
|
export const Demo03StudentApi = {
|
||||||
return await request.post({ url: `/infra/demo03-student/create`, data })
|
// 查询学生分页
|
||||||
}
|
getDemo03StudentPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/infra/demo03-student-erp/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
// 修改学生
|
// 查询学生详情
|
||||||
export const updateDemo03Student = async (data: Demo03StudentVO) => {
|
getDemo03Student: async (id: number) => {
|
||||||
return await request.put({ url: `/infra/demo03-student/update`, data })
|
return await request.get({ url: `/infra/demo03-student-erp/get?id=` + id })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 删除学生
|
// 新增学生
|
||||||
export const deleteDemo03Student = async (id: number) => {
|
createDemo03Student: async (data: Demo03Student) => {
|
||||||
return await request.delete({ url: `/infra/demo03-student/delete?id=` + id })
|
return await request.post({ url: `/infra/demo03-student-erp/create`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 导出学生 Excel
|
// 修改学生
|
||||||
export const exportDemo03Student = async (params) => {
|
updateDemo03Student: async (data: Demo03Student) => {
|
||||||
return await request.download({ url: `/infra/demo03-student/export-excel`, params })
|
return await request.put({ url: `/infra/demo03-student-erp/update`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// 删除学生
|
||||||
|
deleteDemo03Student: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/infra/demo03-student-erp/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 批量删除学生 */
|
||||||
|
deleteDemo03StudentList: async (ids: number[]) => {
|
||||||
|
return await request.delete({ url: `/infra/demo03-student-erp/delete-list?ids=${ids.join(',')}` })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出学生 Excel
|
||||||
|
exportDemo03Student: async (params) => {
|
||||||
|
return await request.download({ url: `/infra/demo03-student-erp/export-excel`, params })
|
||||||
|
},
|
||||||
|
|
||||||
// ==================== 子表(学生课程) ====================
|
// ==================== 子表(学生课程) ====================
|
||||||
|
|
||||||
// 获得学生课程分页
|
// 获得学生课程分页
|
||||||
export const getDemo03CoursePage = async (params) => {
|
getDemo03CoursePage: async (params) => {
|
||||||
return await request.get({ url: `/infra/demo03-student/demo03-course/page`, params })
|
return await request.get({ url: `/infra/demo03-student-erp/demo03-course/page`, params })
|
||||||
}
|
},
|
||||||
// 新增学生课程
|
// 新增学生课程
|
||||||
export const createDemo03Course = async (data) => {
|
createDemo03Course: async (data: Demo03Course) => {
|
||||||
return await request.post({ url: `/infra/demo03-student/demo03-course/create`, data })
|
return await request.post({ url: `/infra/demo03-student-erp/demo03-course/create`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 修改学生课程
|
// 修改学生课程
|
||||||
export const updateDemo03Course = async (data) => {
|
updateDemo03Course: async (data: Demo03Course) => {
|
||||||
return await request.put({ url: `/infra/demo03-student/demo03-course/update`, data })
|
return await request.put({ url: `/infra/demo03-student-erp/demo03-course/update`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 删除学生课程
|
// 删除学生课程
|
||||||
export const deleteDemo03Course = async (id: number) => {
|
deleteDemo03Course: async (id: number) => {
|
||||||
return await request.delete({ url: `/infra/demo03-student/demo03-course/delete?id=` + id })
|
return await request.delete({ url: `/infra/demo03-student-erp/demo03-course/delete?id=` + id })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 获得学生课程
|
/** 批量删除学生课程 */
|
||||||
export const getDemo03Course = async (id: number) => {
|
deleteDemo03CourseList: async (ids: number[]) => {
|
||||||
return await request.get({ url: `/infra/demo03-student/demo03-course/get?id=` + id })
|
return await request.delete({ url: `/infra/demo03-student-erp/demo03-course/delete-list?ids=${ids.join(',')}` })
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// 获得学生课程
|
||||||
|
getDemo03Course: async (id: number) => {
|
||||||
|
return await request.get({ url: `/infra/demo03-student-erp/demo03-course/get?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
// ==================== 子表(学生班级) ====================
|
// ==================== 子表(学生班级) ====================
|
||||||
|
|
||||||
// 获得学生班级分页
|
// 获得学生班级分页
|
||||||
export const getDemo03GradePage = async (params) => {
|
getDemo03GradePage: async (params) => {
|
||||||
return await request.get({ url: `/infra/demo03-student/demo03-grade/page`, params })
|
return await request.get({ url: `/infra/demo03-student-erp/demo03-grade/page`, params })
|
||||||
}
|
},
|
||||||
// 新增学生班级
|
// 新增学生班级
|
||||||
export const createDemo03Grade = async (data) => {
|
createDemo03Grade: async (data: Demo03Grade) => {
|
||||||
return await request.post({ url: `/infra/demo03-student/demo03-grade/create`, data })
|
return await request.post({ url: `/infra/demo03-student-erp/demo03-grade/create`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 修改学生班级
|
// 修改学生班级
|
||||||
export const updateDemo03Grade = async (data) => {
|
updateDemo03Grade: async (data: Demo03Grade) => {
|
||||||
return await request.put({ url: `/infra/demo03-student/demo03-grade/update`, data })
|
return await request.put({ url: `/infra/demo03-student-erp/demo03-grade/update`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 删除学生班级
|
// 删除学生班级
|
||||||
export const deleteDemo03Grade = async (id: number) => {
|
deleteDemo03Grade: async (id: number) => {
|
||||||
return await request.delete({ url: `/infra/demo03-student/demo03-grade/delete?id=` + id })
|
return await request.delete({ url: `/infra/demo03-student-erp/demo03-grade/delete?id=` + id })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 获得学生班级
|
/** 批量删除学生班级 */
|
||||||
export const getDemo03Grade = async (id: number) => {
|
deleteDemo03GradeList: async (ids: number[]) => {
|
||||||
return await request.get({ url: `/infra/demo03-student/demo03-grade/get?id=` + id })
|
return await request.delete({ url: `/infra/demo03-student-erp/demo03-grade/delete-list?ids=${ids.join(',')}` })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获得学生班级
|
||||||
|
getDemo03Grade: async (id: number) => {
|
||||||
|
return await request.get({ url: `/infra/demo03-student-erp/demo03-grade/get?id=` + id })
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,57 +1,81 @@
|
||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
import type { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
export interface Demo03StudentVO {
|
/** 学生课程信息 */
|
||||||
id: number
|
export interface Demo03Course {
|
||||||
name: string
|
id: number; // 编号
|
||||||
sex: number
|
studentId?: number; // 学生编号
|
||||||
birthday: Date
|
name?: string; // 名字
|
||||||
description: string
|
score?: number; // 分数
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询学生分页
|
/** 学生班级信息 */
|
||||||
export const getDemo03StudentPage = async (params) => {
|
export interface Demo03Grade {
|
||||||
return await request.get({ url: `/infra/demo03-student/page`, params })
|
id: number; // 编号
|
||||||
|
studentId?: number; // 学生编号
|
||||||
|
name?: string; // 名字
|
||||||
|
teacher?: string; // 班主任
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询学生详情
|
/** 学生信息 */
|
||||||
export const getDemo03Student = async (id: number) => {
|
export interface Demo03Student {
|
||||||
return await request.get({ url: `/infra/demo03-student/get?id=` + id })
|
id: number; // 编号
|
||||||
|
name?: string; // 名字
|
||||||
|
sex?: number; // 性别
|
||||||
|
birthday?: string | Dayjs; // 出生日期
|
||||||
|
description?: string; // 简介
|
||||||
|
demo03courses?: Demo03Course[]
|
||||||
|
demo03grade?: Demo03Grade
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增学生
|
// 学生 API
|
||||||
export const createDemo03Student = async (data: Demo03StudentVO) => {
|
export const Demo03StudentApi = {
|
||||||
return await request.post({ url: `/infra/demo03-student/create`, data })
|
// 查询学生分页
|
||||||
}
|
getDemo03StudentPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/infra/demo03-student-inner/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
// 修改学生
|
// 查询学生详情
|
||||||
export const updateDemo03Student = async (data: Demo03StudentVO) => {
|
getDemo03Student: async (id: number) => {
|
||||||
return await request.put({ url: `/infra/demo03-student/update`, data })
|
return await request.get({ url: `/infra/demo03-student-inner/get?id=` + id })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 删除学生
|
// 新增学生
|
||||||
export const deleteDemo03Student = async (id: number) => {
|
createDemo03Student: async (data: Demo03Student) => {
|
||||||
return await request.delete({ url: `/infra/demo03-student/delete?id=` + id })
|
return await request.post({ url: `/infra/demo03-student-inner/create`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 导出学生 Excel
|
// 修改学生
|
||||||
export const exportDemo03Student = async (params) => {
|
updateDemo03Student: async (data: Demo03Student) => {
|
||||||
return await request.download({ url: `/infra/demo03-student/export-excel`, params })
|
return await request.put({ url: `/infra/demo03-student-inner/update`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// 删除学生
|
||||||
|
deleteDemo03Student: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/infra/demo03-student-inner/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 批量删除学生 */
|
||||||
|
deleteDemo03StudentList: async (ids: number[]) => {
|
||||||
|
return await request.delete({ url: `/infra/demo03-student-inner/delete-list?ids=${ids.join(',')}` })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出学生 Excel
|
||||||
|
exportDemo03Student: async (params) => {
|
||||||
|
return await request.download({ url: `/infra/demo03-student-inner/export-excel`, params })
|
||||||
|
},
|
||||||
|
|
||||||
// ==================== 子表(学生课程) ====================
|
// ==================== 子表(学生课程) ====================
|
||||||
|
|
||||||
// 获得学生课程列表
|
// 获得学生课程列表
|
||||||
export const getDemo03CourseListByStudentId = async (studentId) => {
|
getDemo03CourseListByStudentId: async (studentId) => {
|
||||||
return await request.get({
|
return await request.get({ url: `/infra/demo03-student-inner/demo03-course/list-by-student-id?studentId=` + studentId })
|
||||||
url: `/infra/demo03-student/demo03-course/list-by-student-id?studentId=` + studentId
|
},
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 子表(学生班级) ====================
|
// ==================== 子表(学生班级) ====================
|
||||||
|
|
||||||
// 获得学生班级
|
// 获得学生班级
|
||||||
export const getDemo03GradeByStudentId = async (studentId) => {
|
getDemo03GradeByStudentId: async (studentId) => {
|
||||||
return await request.get({
|
return await request.get({ url: `/infra/demo03-student-inner/demo03-grade/get-by-student-id?studentId=` + studentId })
|
||||||
url: `/infra/demo03-student/demo03-grade/get-by-student-id?studentId=` + studentId
|
},
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,57 +1,81 @@
|
||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
import type { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
export interface Demo03StudentVO {
|
/** 学生课程信息 */
|
||||||
id: number
|
export interface Demo03Course {
|
||||||
name: string
|
id: number; // 编号
|
||||||
sex: number
|
studentId?: number; // 学生编号
|
||||||
birthday: Date
|
name?: string; // 名字
|
||||||
description: string
|
score?: number; // 分数
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询学生分页
|
/** 学生班级信息 */
|
||||||
export const getDemo03StudentPage = async (params) => {
|
export interface Demo03Grade {
|
||||||
return await request.get({ url: `/infra/demo03-student/page`, params })
|
id: number; // 编号
|
||||||
|
studentId?: number; // 学生编号
|
||||||
|
name?: string; // 名字
|
||||||
|
teacher?: string; // 班主任
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询学生详情
|
/** 学生信息 */
|
||||||
export const getDemo03Student = async (id: number) => {
|
export interface Demo03Student {
|
||||||
return await request.get({ url: `/infra/demo03-student/get?id=` + id })
|
id: number; // 编号
|
||||||
|
name?: string; // 名字
|
||||||
|
sex?: number; // 性别
|
||||||
|
birthday?: string | Dayjs; // 出生日期
|
||||||
|
description?: string; // 简介
|
||||||
|
demo03courses?: Demo03Course[]
|
||||||
|
demo03grade?: Demo03Grade
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增学生
|
// 学生 API
|
||||||
export const createDemo03Student = async (data: Demo03StudentVO) => {
|
export const Demo03StudentApi = {
|
||||||
return await request.post({ url: `/infra/demo03-student/create`, data })
|
// 查询学生分页
|
||||||
}
|
getDemo03StudentPage: async (params: any) => {
|
||||||
|
return await request.get({ url: `/infra/demo03-student-normal/page`, params })
|
||||||
|
},
|
||||||
|
|
||||||
// 修改学生
|
// 查询学生详情
|
||||||
export const updateDemo03Student = async (data: Demo03StudentVO) => {
|
getDemo03Student: async (id: number) => {
|
||||||
return await request.put({ url: `/infra/demo03-student/update`, data })
|
return await request.get({ url: `/infra/demo03-student-normal/get?id=` + id })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 删除学生
|
// 新增学生
|
||||||
export const deleteDemo03Student = async (id: number) => {
|
createDemo03Student: async (data: Demo03Student) => {
|
||||||
return await request.delete({ url: `/infra/demo03-student/delete?id=` + id })
|
return await request.post({ url: `/infra/demo03-student-normal/create`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
// 导出学生 Excel
|
// 修改学生
|
||||||
export const exportDemo03Student = async (params) => {
|
updateDemo03Student: async (data: Demo03Student) => {
|
||||||
return await request.download({ url: `/infra/demo03-student/export-excel`, params })
|
return await request.put({ url: `/infra/demo03-student-normal/update`, data })
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// 删除学生
|
||||||
|
deleteDemo03Student: async (id: number) => {
|
||||||
|
return await request.delete({ url: `/infra/demo03-student-normal/delete?id=` + id })
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 批量删除学生 */
|
||||||
|
deleteDemo03StudentList: async (ids: number[]) => {
|
||||||
|
return await request.delete({ url: `/infra/demo03-student-normal/delete-list?ids=${ids.join(',')}` })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 导出学生 Excel
|
||||||
|
exportDemo03Student: async (params) => {
|
||||||
|
return await request.download({ url: `/infra/demo03-student-normal/export-excel`, params })
|
||||||
|
},
|
||||||
|
|
||||||
// ==================== 子表(学生课程) ====================
|
// ==================== 子表(学生课程) ====================
|
||||||
|
|
||||||
// 获得学生课程列表
|
// 获得学生课程列表
|
||||||
export const getDemo03CourseListByStudentId = async (studentId) => {
|
getDemo03CourseListByStudentId: async (studentId) => {
|
||||||
return await request.get({
|
return await request.get({ url: `/infra/demo03-student-normal/demo03-course/list-by-student-id?studentId=` + studentId })
|
||||||
url: `/infra/demo03-student/demo03-course/list-by-student-id?studentId=` + studentId
|
},
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 子表(学生班级) ====================
|
// ==================== 子表(学生班级) ====================
|
||||||
|
|
||||||
// 获得学生班级
|
// 获得学生班级
|
||||||
export const getDemo03GradeByStudentId = async (studentId) => {
|
getDemo03GradeByStudentId: async (studentId) => {
|
||||||
return await request.get({
|
return await request.get({ url: `/infra/demo03-student-normal/demo03-grade/get-by-student-id?studentId=` + studentId })
|
||||||
url: `/infra/demo03-student/demo03-grade/get-by-student-id?studentId=` + studentId
|
},
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
import { isNumber } from '@/utils/is'
|
import { isNumber } from '@/utils/is'
|
||||||
|
|
||||||
defineOptions({ name: 'Dialog' })
|
defineOptions({ name: 'Dialog' })
|
||||||
|
|
||||||
const slots = useSlots()
|
const slots = useSlots()
|
||||||
|
const emits = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: propTypes.bool.def(false),
|
modelValue: propTypes.bool.def(false),
|
||||||
|
|
@ -55,6 +57,17 @@ const dialogStyle = computed(() => {
|
||||||
height: unref(dialogHeight)
|
height: unref(dialogHeight)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const closing = ref(false)
|
||||||
|
|
||||||
|
function closeHandler() {
|
||||||
|
emits('update:modelValue', false)
|
||||||
|
closing.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function closedHandler() {
|
||||||
|
closing.value = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -68,7 +81,8 @@ const dialogStyle = computed(() => {
|
||||||
draggable
|
draggable
|
||||||
class="com-dialog"
|
class="com-dialog"
|
||||||
:show-close="false"
|
:show-close="false"
|
||||||
@close="$emit('update:modelValue', false)"
|
@close="closeHandler"
|
||||||
|
@closed="closedHandler"
|
||||||
>
|
>
|
||||||
<template #header="{ close }">
|
<template #header="{ close }">
|
||||||
<div class="relative h-54px flex items-center justify-between pl-15px pr-15px">
|
<div class="relative h-54px flex items-center justify-between pl-15px pr-15px">
|
||||||
|
|
@ -102,7 +116,9 @@ const dialogStyle = computed(() => {
|
||||||
</ElScrollbar>
|
</ElScrollbar>
|
||||||
<slot v-else></slot>
|
<slot v-else></slot>
|
||||||
<template v-if="slots.footer" #footer>
|
<template v-if="slots.footer" #footer>
|
||||||
<slot name="footer"></slot>
|
<div :style="{ 'pointer-events': closing ? 'none' : 'auto' }">
|
||||||
|
<slot name="footer"></slot>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ElDialog>
|
</ElDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -23,22 +23,20 @@
|
||||||
|
|
||||||
export default function customTranslate(translations) {
|
export default function customTranslate(translations) {
|
||||||
return function (template, replacements) {
|
return function (template, replacements) {
|
||||||
replacements = replacements || {}
|
replacements = replacements || {};
|
||||||
// Translate
|
// 将模板和翻译字典的键统一转换为小写进行匹配
|
||||||
template = translations[template] || template
|
const lowerTemplate = template.toLowerCase();
|
||||||
|
const translation = Object.keys(translations).find(key => key.toLowerCase() === lowerTemplate);
|
||||||
|
|
||||||
// Replace
|
// 如果找到匹配的翻译,使用翻译后的模板
|
||||||
|
if (translation) {
|
||||||
|
template = translations[translation];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 替换模板中的占位符
|
||||||
return template.replace(/{([^}]+)}/g, function (_, key) {
|
return template.replace(/{([^}]+)}/g, function (_, key) {
|
||||||
let str = replacements[key]
|
// 如果替换值存在,返回替换值;否则返回原始占位符
|
||||||
if (
|
return replacements[key] !== undefined ? replacements[key] : `{${key}}`;
|
||||||
translations[replacements[key]] !== null &&
|
});
|
||||||
translations[replacements[key]] !== undefined
|
};
|
||||||
) {
|
}
|
||||||
// eslint-disable-next-line no-mixed-spaces-and-tabs
|
|
||||||
str = translations[replacements[key]]
|
|
||||||
// eslint-disable-next-line no-mixed-spaces-and-tabs
|
|
||||||
}
|
|
||||||
return str || '{' + key + '}'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -45,8 +45,8 @@ export default {
|
||||||
'Service Task': '服务任务',
|
'Service Task': '服务任务',
|
||||||
'Script Task': '脚本任务',
|
'Script Task': '脚本任务',
|
||||||
'Call Activity': '调用活动',
|
'Call Activity': '调用活动',
|
||||||
'Sub Process (collapsed)': '子流程(折叠的)',
|
'Sub-Process (collapsed)': '子流程(折叠的)',
|
||||||
'Sub Process (expanded)': '子流程(展开的)',
|
'Sub-Process (expanded)': '子流程(展开的)',
|
||||||
'Start Event': '开始事件',
|
'Start Event': '开始事件',
|
||||||
StartEvent: '开始事件',
|
StartEvent: '开始事件',
|
||||||
'Intermediate Throw Event': '中间事件',
|
'Intermediate Throw Event': '中间事件',
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,11 @@
|
||||||
:business-object="elementBusinessObject"
|
:business-object="elementBusinessObject"
|
||||||
/>
|
/>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
|
<!-- 新增的时间事件配置项 -->
|
||||||
|
<el-collapse-item v-if="elementType === 'IntermediateCatchEvent'" name="timeEvent">
|
||||||
|
<template #title><Icon icon="ep:timer" />时间事件</template>
|
||||||
|
<TimeEventConfig :businessObject="bpmnElement.value?.businessObject" :key="elementId" />
|
||||||
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -83,6 +88,8 @@ import ElementProperties from './properties/ElementProperties.vue'
|
||||||
// import ElementForm from './form/ElementForm.vue'
|
// import ElementForm from './form/ElementForm.vue'
|
||||||
import UserTaskListeners from './listeners/UserTaskListeners.vue'
|
import UserTaskListeners from './listeners/UserTaskListeners.vue'
|
||||||
import { getTaskCollapseItemName, isTaskCollapseItemShow } from './task/data'
|
import { getTaskCollapseItemName, isTaskCollapseItemShow } from './task/data'
|
||||||
|
import TimeEventConfig from './time-event-config/TimeEventConfig.vue'
|
||||||
|
import { ref, watch, onMounted } from 'vue'
|
||||||
|
|
||||||
defineOptions({ name: 'MyPropertiesPanel' })
|
defineOptions({ name: 'MyPropertiesPanel' })
|
||||||
|
|
||||||
|
|
@ -121,6 +128,8 @@ const formVisible = ref(false) // 表单配置
|
||||||
const bpmnElement = ref()
|
const bpmnElement = ref()
|
||||||
const isReady = ref(false)
|
const isReady = ref(false)
|
||||||
|
|
||||||
|
const type = ref('time')
|
||||||
|
const condition = ref('')
|
||||||
provide('prefix', props.prefix)
|
provide('prefix', props.prefix)
|
||||||
provide('width', props.width)
|
provide('width', props.width)
|
||||||
|
|
||||||
|
|
@ -141,7 +150,7 @@ const initBpmnInstances = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查所有实例是否都存在
|
// 检查所有实例是否都存在
|
||||||
const allInstancesExist = Object.values(instances).every(instance => instance)
|
const allInstancesExist = Object.values(instances).every((instance) => instance)
|
||||||
if (allInstancesExist) {
|
if (allInstancesExist) {
|
||||||
const w = window as any
|
const w = window as any
|
||||||
w.bpmnInstances = instances
|
w.bpmnInstances = instances
|
||||||
|
|
@ -255,4 +264,48 @@ watch(
|
||||||
activeTab.value = 'base'
|
activeTab.value = 'base'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
function updateNode() {
|
||||||
|
const moddle = window.bpmnInstances?.moddle
|
||||||
|
const modeling = window.bpmnInstances?.modeling
|
||||||
|
const elementRegistry = window.bpmnInstances?.elementRegistry
|
||||||
|
if (!moddle || !modeling || !elementRegistry) return
|
||||||
|
|
||||||
|
const element = elementRegistry.get(props.businessObject.id)
|
||||||
|
if (!element) return
|
||||||
|
|
||||||
|
let timerDef = moddle.create('bpmn:TimerEventDefinition', {})
|
||||||
|
if (type.value === 'time') {
|
||||||
|
timerDef.timeDate = moddle.create('bpmn:FormalExpression', { body: condition.value })
|
||||||
|
} else if (type.value === 'duration') {
|
||||||
|
timerDef.timeDuration = moddle.create('bpmn:FormalExpression', { body: condition.value })
|
||||||
|
} else if (type.value === 'cycle') {
|
||||||
|
timerDef.timeCycle = moddle.create('bpmn:FormalExpression', { body: condition.value })
|
||||||
|
}
|
||||||
|
|
||||||
|
modeling.updateModdleProperties(element, element.businessObject, {
|
||||||
|
eventDefinitions: [timerDef]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化和监听
|
||||||
|
function syncFromBusinessObject() {
|
||||||
|
if (props.businessObject) {
|
||||||
|
const timerDef = (props.businessObject.eventDefinitions || [])[0]
|
||||||
|
if (timerDef) {
|
||||||
|
if (timerDef.timeDate) {
|
||||||
|
type.value = 'time'
|
||||||
|
condition.value = timerDef.timeDate.body
|
||||||
|
} else if (timerDef.timeDuration) {
|
||||||
|
type.value = 'duration'
|
||||||
|
condition.value = timerDef.timeDuration.body
|
||||||
|
} else if (timerDef.timeCycle) {
|
||||||
|
type.value = 'cycle'
|
||||||
|
condition.value = timerDef.timeCycle.body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMounted(syncFromBusinessObject)
|
||||||
|
watch(() => props.businessObject, syncFromBusinessObject, { deep: true })
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,285 @@
|
||||||
|
<template>
|
||||||
|
<el-tabs v-model="tab">
|
||||||
|
<el-tab-pane label="CRON表达式" name="cron">
|
||||||
|
<div style="margin-bottom: 10px">
|
||||||
|
<el-input
|
||||||
|
v-model="cronStr"
|
||||||
|
readonly
|
||||||
|
style="width: 400px; font-weight: bold"
|
||||||
|
:key="'cronStr'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; gap: 8px; margin-bottom: 8px">
|
||||||
|
<el-input v-model="fields.second" placeholder="秒" style="width: 80px" :key="'second'" />
|
||||||
|
<el-input v-model="fields.minute" placeholder="分" style="width: 80px" :key="'minute'" />
|
||||||
|
<el-input v-model="fields.hour" placeholder="时" style="width: 80px" :key="'hour'" />
|
||||||
|
<el-input v-model="fields.day" placeholder="天" style="width: 80px" :key="'day'" />
|
||||||
|
<el-input v-model="fields.month" placeholder="月" style="width: 80px" :key="'month'" />
|
||||||
|
<el-input v-model="fields.week" placeholder="周" style="width: 80px" :key="'week'" />
|
||||||
|
<el-input v-model="fields.year" placeholder="年" style="width: 80px" :key="'year'" />
|
||||||
|
</div>
|
||||||
|
<el-tabs v-model="activeField" type="card" style="margin-bottom: 8px">
|
||||||
|
<el-tab-pane v-for="f in cronFieldList" :label="f.label" :name="f.key" :key="f.key">
|
||||||
|
<div style="margin-bottom: 8px">
|
||||||
|
<el-radio-group v-model="cronMode[f.key]" :key="'radio-' + f.key">
|
||||||
|
<el-radio label="every" :key="'every-' + f.key">每{{ f.label }}</el-radio>
|
||||||
|
<el-radio label="range" :key="'range-' + f.key"
|
||||||
|
>从
|
||||||
|
<el-input-number
|
||||||
|
v-model="cronRange[f.key][0]"
|
||||||
|
:min="f.min"
|
||||||
|
:max="f.max"
|
||||||
|
size="small"
|
||||||
|
style="width: 60px"
|
||||||
|
:key="'range0-' + f.key"
|
||||||
|
/>
|
||||||
|
到
|
||||||
|
<el-input-number
|
||||||
|
v-model="cronRange[f.key][1]"
|
||||||
|
:min="f.min"
|
||||||
|
:max="f.max"
|
||||||
|
size="small"
|
||||||
|
style="width: 60px"
|
||||||
|
:key="'range1-' + f.key"
|
||||||
|
/>
|
||||||
|
之间每{{ f.label }}</el-radio
|
||||||
|
>
|
||||||
|
<el-radio label="step" :key="'step-' + f.key"
|
||||||
|
>从第
|
||||||
|
<el-input-number
|
||||||
|
v-model="cronStep[f.key][0]"
|
||||||
|
:min="f.min"
|
||||||
|
:max="f.max"
|
||||||
|
size="small"
|
||||||
|
style="width: 60px"
|
||||||
|
:key="'step0-' + f.key"
|
||||||
|
/>
|
||||||
|
开始每
|
||||||
|
<el-input-number
|
||||||
|
v-model="cronStep[f.key][1]"
|
||||||
|
:min="1"
|
||||||
|
:max="f.max"
|
||||||
|
size="small"
|
||||||
|
style="width: 60px"
|
||||||
|
:key="'step1-' + f.key"
|
||||||
|
/>
|
||||||
|
{{ f.label }}</el-radio
|
||||||
|
>
|
||||||
|
<el-radio label="appoint" :key="'appoint-' + f.key">指定</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</div>
|
||||||
|
<div v-if="cronMode[f.key] === 'appoint'">
|
||||||
|
<el-checkbox-group v-model="cronAppoint[f.key]" :key="'group-' + f.key">
|
||||||
|
<el-checkbox
|
||||||
|
v-for="n in f.max + 1"
|
||||||
|
:label="pad(n - 1)"
|
||||||
|
:key="'cb-' + f.key + '-' + (n - 1)"
|
||||||
|
>{{ pad(n - 1) }}</el-checkbox
|
||||||
|
>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="标准格式" name="iso" :key="'iso-tab'">
|
||||||
|
<div style="margin-bottom: 10px">
|
||||||
|
<el-input
|
||||||
|
v-model="isoStr"
|
||||||
|
placeholder="如R1/2025-05-21T21:59:54/P3DT30M30S"
|
||||||
|
style="width: 400px; font-weight: bold"
|
||||||
|
:key="'isoStr'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style="margin-bottom: 10px"
|
||||||
|
>循环次数:<el-input-number v-model="repeat" :min="1" style="width: 100px" :key="'repeat'"
|
||||||
|
/></div>
|
||||||
|
<div style="margin-bottom: 10px"
|
||||||
|
>日期时间:<el-date-picker
|
||||||
|
v-model="isoDate"
|
||||||
|
type="datetime"
|
||||||
|
placeholder="选择日期时间"
|
||||||
|
style="width: 200px"
|
||||||
|
:key="'isoDate'"
|
||||||
|
/></div>
|
||||||
|
<div style="margin-bottom: 10px"
|
||||||
|
>当前时长:<el-input
|
||||||
|
v-model="isoDuration"
|
||||||
|
placeholder="如P3DT30M30S"
|
||||||
|
style="width: 200px"
|
||||||
|
:key="'isoDuration'"
|
||||||
|
/></div>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
>秒:<el-button
|
||||||
|
v-for="s in [5, 10, 30, 50]"
|
||||||
|
@click="setDuration('S', s)"
|
||||||
|
:key="'sec-' + s"
|
||||||
|
>{{ s }}</el-button
|
||||||
|
>自定义</div
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
>分:<el-button
|
||||||
|
v-for="m in [5, 10, 30, 50]"
|
||||||
|
@click="setDuration('M', m)"
|
||||||
|
:key="'min-' + m"
|
||||||
|
>{{ m }}</el-button
|
||||||
|
>自定义</div
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
>小时:<el-button
|
||||||
|
v-for="h in [4, 8, 12, 24]"
|
||||||
|
@click="setDuration('H', h)"
|
||||||
|
:key="'hour-' + h"
|
||||||
|
>{{ h }}</el-button
|
||||||
|
>自定义</div
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
>天:<el-button
|
||||||
|
v-for="d in [1, 2, 3, 4]"
|
||||||
|
@click="setDuration('D', d)"
|
||||||
|
:key="'day-' + d"
|
||||||
|
>{{ d }}</el-button
|
||||||
|
>自定义</div
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
>月:<el-button
|
||||||
|
v-for="mo in [1, 2, 3, 4]"
|
||||||
|
@click="setDuration('M', mo)"
|
||||||
|
:key="'mon-' + mo"
|
||||||
|
>{{ mo }}</el-button
|
||||||
|
>自定义</div
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
>年:<el-button
|
||||||
|
v-for="y in [1, 2, 3, 4]"
|
||||||
|
@click="setDuration('Y', y)"
|
||||||
|
:key="'year-' + y"
|
||||||
|
>{{ y }}</el-button
|
||||||
|
>自定义</div
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch, computed } from 'vue'
|
||||||
|
const props = defineProps({ value: String })
|
||||||
|
const emit = defineEmits(['change'])
|
||||||
|
|
||||||
|
const tab = ref('cron')
|
||||||
|
const cronStr = ref(props.value || '* * * * * ?')
|
||||||
|
const fields = ref({
|
||||||
|
second: '*',
|
||||||
|
minute: '*',
|
||||||
|
hour: '*',
|
||||||
|
day: '*',
|
||||||
|
month: '*',
|
||||||
|
week: '?',
|
||||||
|
year: ''
|
||||||
|
})
|
||||||
|
const cronFieldList = [
|
||||||
|
{ key: 'second', label: '秒', min: 0, max: 59 },
|
||||||
|
{ key: 'minute', label: '分', min: 0, max: 59 },
|
||||||
|
{ key: 'hour', label: '时', min: 0, max: 23 },
|
||||||
|
{ key: 'day', label: '天', min: 1, max: 31 },
|
||||||
|
{ key: 'month', label: '月', min: 1, max: 12 },
|
||||||
|
{ key: 'week', label: '周', min: 1, max: 7 },
|
||||||
|
{ key: 'year', label: '年', min: 1970, max: 2099 }
|
||||||
|
]
|
||||||
|
const activeField = ref('second')
|
||||||
|
const cronMode = ref({
|
||||||
|
second: 'appoint',
|
||||||
|
minute: 'every',
|
||||||
|
hour: 'every',
|
||||||
|
day: 'every',
|
||||||
|
month: 'every',
|
||||||
|
week: 'every',
|
||||||
|
year: 'every'
|
||||||
|
})
|
||||||
|
const cronAppoint = ref({
|
||||||
|
second: ['00', '01'],
|
||||||
|
minute: [],
|
||||||
|
hour: [],
|
||||||
|
day: [],
|
||||||
|
month: [],
|
||||||
|
week: [],
|
||||||
|
year: []
|
||||||
|
})
|
||||||
|
const cronRange = ref({
|
||||||
|
second: [0, 1],
|
||||||
|
minute: [0, 1],
|
||||||
|
hour: [0, 1],
|
||||||
|
day: [1, 2],
|
||||||
|
month: [1, 2],
|
||||||
|
week: [1, 2],
|
||||||
|
year: [1970, 1971]
|
||||||
|
})
|
||||||
|
const cronStep = ref({
|
||||||
|
second: [1, 1],
|
||||||
|
minute: [1, 1],
|
||||||
|
hour: [1, 1],
|
||||||
|
day: [1, 1],
|
||||||
|
month: [1, 1],
|
||||||
|
week: [1, 1],
|
||||||
|
year: [1970, 1]
|
||||||
|
})
|
||||||
|
|
||||||
|
function pad(n) {
|
||||||
|
return n < 10 ? '0' + n : '' + n
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
[fields, cronMode, cronAppoint, cronRange, cronStep],
|
||||||
|
() => {
|
||||||
|
// 组装cron表达式
|
||||||
|
let arr = cronFieldList.map((f) => {
|
||||||
|
if (cronMode.value[f.key] === 'every') return '*'
|
||||||
|
if (cronMode.value[f.key] === 'appoint') return cronAppoint.value[f.key].join(',') || '*'
|
||||||
|
if (cronMode.value[f.key] === 'range')
|
||||||
|
return `${cronRange.value[f.key][0]}-${cronRange.value[f.key][1]}`
|
||||||
|
if (cronMode.value[f.key] === 'step')
|
||||||
|
return `${cronStep.value[f.key][0]}/${cronStep.value[f.key][1]}`
|
||||||
|
return fields.value[f.key] || '*'
|
||||||
|
})
|
||||||
|
// week和year特殊处理
|
||||||
|
arr[5] = arr[5] || '?'
|
||||||
|
cronStr.value = arr.join(' ')
|
||||||
|
if (tab.value === 'cron') emit('change', cronStr.value)
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 标准格式
|
||||||
|
const isoStr = ref('')
|
||||||
|
const repeat = ref(1)
|
||||||
|
const isoDate = ref('')
|
||||||
|
const isoDuration = ref('')
|
||||||
|
function setDuration(type, val) {
|
||||||
|
// 组装ISO 8601字符串
|
||||||
|
let d = isoDuration.value
|
||||||
|
if (!d.includes(type)) d += val + type
|
||||||
|
else d = d.replace(new RegExp(`\\d+${type}`), val + type)
|
||||||
|
isoDuration.value = d
|
||||||
|
updateIsoStr()
|
||||||
|
}
|
||||||
|
function updateIsoStr() {
|
||||||
|
let str = `R${repeat.value}`
|
||||||
|
if (isoDate.value)
|
||||||
|
str +=
|
||||||
|
'/' +
|
||||||
|
(typeof isoDate.value === 'string' ? isoDate.value : new Date(isoDate.value).toISOString())
|
||||||
|
if (isoDuration.value) str += '/' + isoDuration.value
|
||||||
|
isoStr.value = str
|
||||||
|
if (tab.value === 'iso') emit('change', isoStr.value)
|
||||||
|
}
|
||||||
|
watch([repeat, isoDate, isoDuration], updateIsoStr)
|
||||||
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
(val) => {
|
||||||
|
if (!val) return
|
||||||
|
if (tab.value === 'cron') cronStr.value = val
|
||||||
|
if (tab.value === 'iso') isoStr.value = val
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div style="margin-bottom: 10px"
|
||||||
|
>当前选择:<el-input v-model="isoString" readonly style="width: 300px"
|
||||||
|
/></div>
|
||||||
|
<div v-for="unit in units" :key="unit.key" style="margin-bottom: 8px">
|
||||||
|
<span>{{ unit.label }}:</span>
|
||||||
|
<el-button-group>
|
||||||
|
<el-button
|
||||||
|
v-for="val in unit.presets"
|
||||||
|
:key="val"
|
||||||
|
size="mini"
|
||||||
|
@click="setUnit(unit.key, val)"
|
||||||
|
>{{ val }}</el-button
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model.number="custom[unit.key]"
|
||||||
|
size="mini"
|
||||||
|
style="width: 60px; margin-left: 8px"
|
||||||
|
placeholder="自定义"
|
||||||
|
@change="setUnit(unit.key, custom[unit.key])"
|
||||||
|
/>
|
||||||
|
</el-button-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch, computed } from 'vue'
|
||||||
|
const props = defineProps({ value: String })
|
||||||
|
const emit = defineEmits(['change'])
|
||||||
|
|
||||||
|
const units = [
|
||||||
|
{ key: 'Y', label: '年', presets: [1, 2, 3, 4] },
|
||||||
|
{ key: 'M', label: '月', presets: [1, 2, 3, 4] },
|
||||||
|
{ key: 'D', label: '天', presets: [1, 2, 3, 4] },
|
||||||
|
{ key: 'H', label: '时', presets: [4, 8, 12, 24] },
|
||||||
|
{ key: 'm', label: '分', presets: [5, 10, 30, 50] },
|
||||||
|
{ key: 'S', label: '秒', presets: [5, 10, 30, 50] }
|
||||||
|
]
|
||||||
|
const custom = ref({ Y: '', M: '', D: '', H: '', m: '', S: '' })
|
||||||
|
const isoString = ref('')
|
||||||
|
|
||||||
|
function setUnit(key, val) {
|
||||||
|
if (!val || isNaN(val)) {
|
||||||
|
custom.value[key] = ''
|
||||||
|
return
|
||||||
|
}
|
||||||
|
custom.value[key] = val
|
||||||
|
updateIsoString()
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateIsoString() {
|
||||||
|
let str = 'P'
|
||||||
|
if (custom.value.Y) str += custom.value.Y + 'Y'
|
||||||
|
if (custom.value.M) str += custom.value.M + 'M'
|
||||||
|
if (custom.value.D) str += custom.value.D + 'D'
|
||||||
|
if (custom.value.H || custom.value.m || custom.value.S) str += 'T'
|
||||||
|
if (custom.value.H) str += custom.value.H + 'H'
|
||||||
|
if (custom.value.m) str += custom.value.m + 'M'
|
||||||
|
if (custom.value.S) str += custom.value.S + 'S'
|
||||||
|
isoString.value = str === 'P' ? '' : str
|
||||||
|
emit('change', isoString.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
(val) => {
|
||||||
|
if (!val) return
|
||||||
|
// 解析ISO 8601字符串到custom
|
||||||
|
const match = val.match(
|
||||||
|
/^P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/
|
||||||
|
)
|
||||||
|
if (match) {
|
||||||
|
custom.value.Y = match[1] || ''
|
||||||
|
custom.value.M = match[2] || ''
|
||||||
|
custom.value.D = match[3] || ''
|
||||||
|
custom.value.H = match[4] || ''
|
||||||
|
custom.value.m = match[5] || ''
|
||||||
|
custom.value.S = match[6] || ''
|
||||||
|
updateIsoString()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,312 @@
|
||||||
|
<template>
|
||||||
|
<div class="panel-tab__content">
|
||||||
|
<div style="margin-top: 10px">
|
||||||
|
<span>类型:</span>
|
||||||
|
<el-button-group>
|
||||||
|
<el-button size="mini" :type="type === 'time' ? 'primary' : ''" @click="setType('time')"
|
||||||
|
>时间</el-button
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
:type="type === 'duration' ? 'primary' : ''"
|
||||||
|
@click="setType('duration')"
|
||||||
|
>持续</el-button
|
||||||
|
>
|
||||||
|
<el-button size="mini" :type="type === 'cycle' ? 'primary' : ''" @click="setType('cycle')"
|
||||||
|
>循环</el-button
|
||||||
|
>
|
||||||
|
</el-button-group>
|
||||||
|
<el-icon v-if="valid" color="green" style="margin-left: 8px"><CircleCheckFilled /></el-icon>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 10px; display: flex; align-items: center">
|
||||||
|
<span>条件:</span>
|
||||||
|
<el-input
|
||||||
|
v-model="condition"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
style="width: calc(100% - 100px)"
|
||||||
|
:readonly="type !== 'duration' && type !== 'cycle'"
|
||||||
|
@focus="handleInputFocus"
|
||||||
|
@blur="updateNode"
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<el-tooltip v-if="!valid" content="格式错误" placement="top">
|
||||||
|
<el-icon color="orange"><WarningFilled /></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip :content="helpText" placement="top">
|
||||||
|
<el-icon color="#409EFF" style="cursor: pointer" @click="showHelp = true"
|
||||||
|
><QuestionFilled
|
||||||
|
/></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-button
|
||||||
|
v-if="type === 'time'"
|
||||||
|
@click="showDatePicker = true"
|
||||||
|
style="margin-left: 4px"
|
||||||
|
circle
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:calendar" />
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="type === 'duration'"
|
||||||
|
@click="showDurationDialog = true"
|
||||||
|
style="margin-left: 4px"
|
||||||
|
circle
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:timer" />
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="type === 'cycle'"
|
||||||
|
@click="showCycleDialog = true"
|
||||||
|
style="margin-left: 4px"
|
||||||
|
circle
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:setting" />
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<!-- 时间选择器 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="showDatePicker"
|
||||||
|
title="选择时间"
|
||||||
|
width="400px"
|
||||||
|
@close="showDatePicker = false"
|
||||||
|
>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateValue"
|
||||||
|
type="datetime"
|
||||||
|
placeholder="选择日期时间"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="onDateChange"
|
||||||
|
/>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="showDatePicker = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="onDateConfirm">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 持续时长选择器 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="showDurationDialog"
|
||||||
|
title="时间配置"
|
||||||
|
width="600px"
|
||||||
|
@close="showDurationDialog = false"
|
||||||
|
>
|
||||||
|
<DurationConfig :value="condition" @change="onDurationChange" />
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="showDurationDialog = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="onDurationConfirm">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 循环配置器 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="showCycleDialog"
|
||||||
|
title="时间配置"
|
||||||
|
width="800px"
|
||||||
|
@close="showCycleDialog = false"
|
||||||
|
>
|
||||||
|
<CycleConfig :value="condition" @change="onCycleChange" />
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="showCycleDialog = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="onCycleConfirm">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 帮助说明 -->
|
||||||
|
<el-dialog v-model="showHelp" title="格式说明" width="600px" @close="showHelp = false">
|
||||||
|
<div v-html="helpHtml"></div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="showHelp = false">关闭</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, computed, watch, onMounted } from 'vue'
|
||||||
|
import { CircleCheckFilled, WarningFilled, QuestionFilled } from '@element-plus/icons-vue'
|
||||||
|
import DurationConfig from './DurationConfig.vue'
|
||||||
|
import CycleConfig from './CycleConfig.vue'
|
||||||
|
import { createListenerObject, updateElementExtensions } from '../../utils'
|
||||||
|
const bpmnInstances = () => (window as any).bpmnInstances
|
||||||
|
const props = defineProps({ businessObject: Object })
|
||||||
|
const type = ref('time')
|
||||||
|
const condition = ref('')
|
||||||
|
const valid = ref(true)
|
||||||
|
const showDatePicker = ref(false)
|
||||||
|
const showDurationDialog = ref(false)
|
||||||
|
const showCycleDialog = ref(false)
|
||||||
|
const showHelp = ref(false)
|
||||||
|
const dateValue = ref(null)
|
||||||
|
const bpmnElement = ref(null)
|
||||||
|
|
||||||
|
const placeholder = computed(() => {
|
||||||
|
if (type.value === 'time') return '请输入时间'
|
||||||
|
if (type.value === 'duration') return '请输入持续时长'
|
||||||
|
if (type.value === 'cycle') return '请输入循环表达式'
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
const helpText = computed(() => {
|
||||||
|
if (type.value === 'time') return '选择具体时间'
|
||||||
|
if (type.value === 'duration') return 'ISO 8601格式,如PT1H'
|
||||||
|
if (type.value === 'cycle') return 'CRON表达式或ISO 8601周期'
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
const helpHtml = computed(() => {
|
||||||
|
if (type.value === 'duration') {
|
||||||
|
return `指定定时器之前要等待多长时间。S表示秒,M表示分,D表示天;P表示时间段,T表示精确到时间的时间段。<br>
|
||||||
|
时间格式依然为ISO 8601格式,一年两个月三天四小时五分六秒内,可以写成P1Y2M3DT4H5M6S。<br>
|
||||||
|
P是开始标记,T是时间和日期分割标记,没有日期只有时间T是不能省去的,比如1小时执行一次应写成PT1H。`
|
||||||
|
}
|
||||||
|
if (type.value === 'cycle') {
|
||||||
|
return `支持CRON表达式(如0 0/30 * * * ?)或ISO 8601周期(如R3/PT10M)。`
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 初始化和监听
|
||||||
|
function syncFromBusinessObject() {
|
||||||
|
if (props.businessObject) {
|
||||||
|
const timerDef = (props.businessObject.eventDefinitions || [])[0]
|
||||||
|
if (timerDef) {
|
||||||
|
if (timerDef.timeDate) {
|
||||||
|
type.value = 'time'
|
||||||
|
condition.value = timerDef.timeDate.body
|
||||||
|
} else if (timerDef.timeDuration) {
|
||||||
|
type.value = 'duration'
|
||||||
|
condition.value = timerDef.timeDuration.body
|
||||||
|
} else if (timerDef.timeCycle) {
|
||||||
|
type.value = 'cycle'
|
||||||
|
condition.value = timerDef.timeCycle.body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMounted(syncFromBusinessObject)
|
||||||
|
|
||||||
|
// 切换类型
|
||||||
|
function setType(t) {
|
||||||
|
type.value = t
|
||||||
|
condition.value = ''
|
||||||
|
updateNode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 输入校验
|
||||||
|
watch([type, condition], () => {
|
||||||
|
valid.value = validate()
|
||||||
|
// updateNode() // 可以注释掉,避免频繁触发
|
||||||
|
})
|
||||||
|
|
||||||
|
function validate() {
|
||||||
|
if (type.value === 'time') {
|
||||||
|
return !!condition.value && !isNaN(Date.parse(condition.value))
|
||||||
|
}
|
||||||
|
if (type.value === 'duration') {
|
||||||
|
return /^P.*$/.test(condition.value)
|
||||||
|
}
|
||||||
|
if (type.value === 'cycle') {
|
||||||
|
return /^([0-9*\/?, ]+|R\d*\/P.*)$/.test(condition.value)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择时间
|
||||||
|
function onDateChange(val) {
|
||||||
|
dateValue.value = val
|
||||||
|
}
|
||||||
|
function onDateConfirm() {
|
||||||
|
if (dateValue.value) {
|
||||||
|
condition.value = new Date(dateValue.value).toISOString()
|
||||||
|
showDatePicker.value = false
|
||||||
|
updateNode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 持续时长
|
||||||
|
function onDurationChange(val) {
|
||||||
|
condition.value = val
|
||||||
|
}
|
||||||
|
function onDurationConfirm() {
|
||||||
|
showDurationDialog.value = false
|
||||||
|
updateNode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 循环
|
||||||
|
function onCycleChange(val) {
|
||||||
|
condition.value = val
|
||||||
|
}
|
||||||
|
function onCycleConfirm() {
|
||||||
|
showCycleDialog.value = false
|
||||||
|
updateNode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 输入框聚焦时弹窗(可选)
|
||||||
|
function handleInputFocus() {
|
||||||
|
if (type.value === 'time') showDatePicker.value = true
|
||||||
|
if (type.value === 'duration') showDurationDialog.value = true
|
||||||
|
if (type.value === 'cycle') showCycleDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同步到节点
|
||||||
|
function updateNode() {
|
||||||
|
const moddle = window.bpmnInstances?.moddle
|
||||||
|
const modeling = window.bpmnInstances?.modeling
|
||||||
|
const elementRegistry = window.bpmnInstances?.elementRegistry
|
||||||
|
if (!moddle || !modeling || !elementRegistry) return
|
||||||
|
|
||||||
|
// 获取元素
|
||||||
|
if (!props.businessObject || !props.businessObject.id) return
|
||||||
|
const element = elementRegistry.get(props.businessObject.id)
|
||||||
|
if (!element) return
|
||||||
|
|
||||||
|
// 1. 复用原有 timerDef,或新建
|
||||||
|
let timerDef =
|
||||||
|
element.businessObject.eventDefinitions && element.businessObject.eventDefinitions[0]
|
||||||
|
if (!timerDef) {
|
||||||
|
timerDef = bpmnInstances().bpmnFactory.create('bpmn:TimerEventDefinition', {})
|
||||||
|
modeling.updateProperties(element, {
|
||||||
|
eventDefinitions: [timerDef]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 清空原有
|
||||||
|
delete timerDef.timeDate
|
||||||
|
delete timerDef.timeDuration
|
||||||
|
delete timerDef.timeCycle
|
||||||
|
|
||||||
|
// 3. 设置新的
|
||||||
|
if (type.value === 'time' && condition.value) {
|
||||||
|
timerDef.timeDate = bpmnInstances().bpmnFactory.create('bpmn:FormalExpression', {
|
||||||
|
body: condition.value
|
||||||
|
})
|
||||||
|
} else if (type.value === 'duration' && condition.value) {
|
||||||
|
timerDef.timeDuration = bpmnInstances().bpmnFactory.create('bpmn:FormalExpression', {
|
||||||
|
body: condition.value
|
||||||
|
})
|
||||||
|
} else if (type.value === 'cycle' && condition.value) {
|
||||||
|
timerDef.timeCycle = bpmnInstances().bpmnFactory.create('bpmn:FormalExpression', {
|
||||||
|
body: condition.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
bpmnInstances().modeling.updateProperties(toRaw(element), {
|
||||||
|
eventDefinitions: [timerDef]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.businessObject,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
nextTick(() => {
|
||||||
|
syncFromBusinessObject()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 相关样式 */
|
||||||
|
</style>
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import { defineStore } from 'pinia'
|
|
||||||
import { store } from '../index'
|
|
||||||
import { humpToUnderline, setCssVar } from '@/utils'
|
|
||||||
import { ElMessage } from 'element-plus'
|
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
||||||
import { ElementPlusSize } from '@/types/elementPlus'
|
import { ElementPlusSize } from '@/types/elementPlus'
|
||||||
import { LayoutType } from '@/types/layout'
|
import { LayoutType } from '@/types/layout'
|
||||||
import { ThemeTypes } from '@/types/theme'
|
import { ThemeTypes } from '@/types/theme'
|
||||||
|
import { humpToUnderline, setCssVar } from '@/utils'
|
||||||
|
import { getCssColorVariable, hexToRGB, mix } from '@/utils/color'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { store } from '../index'
|
||||||
|
|
||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
|
|
||||||
|
|
@ -183,6 +184,40 @@ export const useAppStore = defineStore('app', {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
setPrimaryLight() {
|
||||||
|
if (this.theme.elColorPrimary) {
|
||||||
|
const elColorPrimary = this.theme.elColorPrimary
|
||||||
|
const color = this.isDark ? '#000000' : '#ffffff'
|
||||||
|
const lightList = [3, 5, 7, 8, 9]
|
||||||
|
lightList.forEach((v) => {
|
||||||
|
setCssVar(`--el-color-primary-light-${v}`, mix(color, elColorPrimary, v / 10))
|
||||||
|
})
|
||||||
|
setCssVar(`--el-color-primary-dark-2`, mix(color, elColorPrimary, 0.2))
|
||||||
|
|
||||||
|
this.setAllColorRgbVars()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理element自带的主题色和辅助色的-rgb切换主题变化,如:--el-color-primary-rgb
|
||||||
|
setAllColorRgbVars() {
|
||||||
|
// 需要处理的颜色类型列表
|
||||||
|
const colorTypes = ['primary', 'success', 'warning', 'danger', 'error', 'info']
|
||||||
|
|
||||||
|
colorTypes.forEach((type) => {
|
||||||
|
// 获取当前颜色值
|
||||||
|
const colorValue = getCssColorVariable(`--el-color-${type}`)
|
||||||
|
if (colorValue) {
|
||||||
|
// 转换为rgba并提取RGB部分
|
||||||
|
const rgbaString = hexToRGB(colorValue, 1)
|
||||||
|
const rgbValues = rgbaString.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/i)
|
||||||
|
if (rgbValues) {
|
||||||
|
const [, r, g, b] = rgbValues
|
||||||
|
// 设置对应的RGB变量
|
||||||
|
setCssVar(`--el-color-${type}-rgb`, `${r}, ${g}, ${b}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
setBreadcrumb(breadcrumb: boolean) {
|
setBreadcrumb(breadcrumb: boolean) {
|
||||||
this.breadcrumb = breadcrumb
|
this.breadcrumb = breadcrumb
|
||||||
},
|
},
|
||||||
|
|
@ -256,6 +291,7 @@ export const useAppStore = defineStore('app', {
|
||||||
document.documentElement.classList.remove('dark')
|
document.documentElement.classList.remove('dark')
|
||||||
}
|
}
|
||||||
wsCache.set(CACHE_KEY.IS_DARK, this.isDark)
|
wsCache.set(CACHE_KEY.IS_DARK, this.isDark)
|
||||||
|
this.setPrimaryLight()
|
||||||
},
|
},
|
||||||
setCurrentSize(currentSize: ElementPlusSize) {
|
setCurrentSize(currentSize: ElementPlusSize) {
|
||||||
this.currentSize = currentSize
|
this.currentSize = currentSize
|
||||||
|
|
@ -272,6 +308,7 @@ export const useAppStore = defineStore('app', {
|
||||||
for (const key in this.theme) {
|
for (const key in this.theme) {
|
||||||
setCssVar(`--${humpToUnderline(key)}`, this.theme[key])
|
setCssVar(`--${humpToUnderline(key)}`, this.theme[key])
|
||||||
}
|
}
|
||||||
|
this.setPrimaryLight()
|
||||||
},
|
},
|
||||||
setFooter(footer: boolean) {
|
setFooter(footer: boolean) {
|
||||||
this.footer = footer
|
this.footer = footer
|
||||||
|
|
|
||||||
|
|
@ -172,3 +172,46 @@ export const PREDEFINE_COLORS = [
|
||||||
'#1f73c3',
|
'#1f73c3',
|
||||||
'#711f57'
|
'#711f57'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mixes two colors.
|
||||||
|
*
|
||||||
|
* @param {string} color1 - The first color, should be a 6-digit hexadecimal color code starting with `#`.
|
||||||
|
* @param {string} color2 - The second color, should be a 6-digit hexadecimal color code starting with `#`.
|
||||||
|
* @param {number} [weight=0.5] - The weight of color1 in the mix, should be a number between 0 and 1, where 0 represents 100% of color2, and 1 represents 100% of color1.
|
||||||
|
* @returns {string} The mixed color, a 6-digit hexadecimal color code starting with `#`.
|
||||||
|
*/
|
||||||
|
export const mix = (color1: string, color2: string, weight: number = 0.5): string => {
|
||||||
|
let color = '#'
|
||||||
|
for (let i = 0; i <= 2; i++) {
|
||||||
|
const c1 = parseInt(color1.substring(1 + i * 2, 3 + i * 2), 16)
|
||||||
|
const c2 = parseInt(color2.substring(1 + i * 2, 3 + i * 2), 16)
|
||||||
|
const c = Math.round(c1 * weight + c2 * (1 - weight))
|
||||||
|
color += c.toString(16).padStart(2, '0')
|
||||||
|
}
|
||||||
|
return color
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getCssColorVariable
|
||||||
|
* @description 获取css变量的颜色值
|
||||||
|
* @param colorVariable css变量名
|
||||||
|
* @param opacity 透明度
|
||||||
|
* @returns {string} 颜色值
|
||||||
|
* @example getCssColorVariable('--el-color-primary', 0.5)
|
||||||
|
* @example getCssColorVariable('--el-color-primary')
|
||||||
|
* @example getCssColorVariable()
|
||||||
|
*/
|
||||||
|
export const getCssColorVariable = (
|
||||||
|
colorVariable: string = '--el-color-primary',
|
||||||
|
opacity?: number
|
||||||
|
) => {
|
||||||
|
const colorValue = getComputedStyle(document.documentElement)
|
||||||
|
.getPropertyValue(colorVariable)
|
||||||
|
.trim()
|
||||||
|
if (colorValue) {
|
||||||
|
return opacity ? hexToRGB(colorValue, opacity) : colorValue
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,20 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="字典类型" min-width="12%">
|
<el-table-column label="字典类型" min-width="12%">
|
||||||
<template #default="scope">
|
<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
|
<el-option
|
||||||
v-for="dict in dictOptions"
|
v-for="dict in dictOptions"
|
||||||
:key="dict.id"
|
:key="dict.id"
|
||||||
|
|
@ -114,6 +127,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { PropType } from 'vue'
|
import { PropType } from 'vue'
|
||||||
|
import { Refresh } from '@element-plus/icons-vue'
|
||||||
import * as CodegenApi from '@/api/infra/codegen'
|
import * as CodegenApi from '@/api/infra/codegen'
|
||||||
import * as DictDataApi from '@/api/system/dict/dict.type'
|
import * as DictDataApi from '@/api/system/dict/dict.type'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:value="dict.value"
|
:label="dict.value"
|
||||||
>
|
>
|
||||||
{{ dict.label }}
|
{{ dict.label }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
|
|
@ -44,7 +44,10 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
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 { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
@ -59,13 +62,13 @@ const formData = ref({
|
||||||
sex: undefined,
|
sex: undefined,
|
||||||
birthday: undefined,
|
birthday: undefined,
|
||||||
description: undefined,
|
description: undefined,
|
||||||
avatar: undefined
|
avatar: undefined,
|
||||||
})
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
||||||
sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
|
sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
|
||||||
birthday: [{ 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
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
|
@ -95,7 +98,7 @@ const submitForm = async () => {
|
||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value as unknown as Demo01ContactApi.Demo01ContactVO
|
const data = formData.value as unknown as Demo01Contact
|
||||||
if (formType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
await Demo01ContactApi.createDemo01Contact(data)
|
await Demo01ContactApi.createDemo01Contact(data)
|
||||||
message.success(t('common.createSuccess'))
|
message.success(t('common.createSuccess'))
|
||||||
|
|
@ -119,7 +122,7 @@ const resetForm = () => {
|
||||||
sex: undefined,
|
sex: undefined,
|
||||||
birthday: undefined,
|
birthday: undefined,
|
||||||
description: undefined,
|
description: undefined,
|
||||||
avatar: undefined
|
avatar: undefined,
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
<template>
|
<template>
|
||||||
<doc-alert title="代码生成(单表)" url="https://doc.iocoder.cn/new-feature/" />
|
|
||||||
|
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<!-- 搜索工作栏 -->
|
<!-- 搜索工作栏 -->
|
||||||
<el-form
|
<el-form
|
||||||
|
|
@ -20,7 +18,12 @@
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="性别" prop="sex">
|
<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
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
|
|
@ -37,7 +40,7 @@
|
||||||
start-placeholder="开始日期"
|
start-placeholder="开始日期"
|
||||||
end-placeholder="结束日期"
|
end-placeholder="结束日期"
|
||||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
: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>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
|
|
@ -60,13 +63,30 @@
|
||||||
>
|
>
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
</el-button>
|
</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-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<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="id" />
|
||||||
<el-table-column label="名字" align="center" prop="name" />
|
<el-table-column label="名字" align="center" prop="name" />
|
||||||
<el-table-column label="性别" align="center" prop="sex">
|
<el-table-column label="性别" align="center" prop="sex">
|
||||||
|
|
@ -90,7 +110,7 @@
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
width="180px"
|
width="180px"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
@ -126,25 +146,27 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { isEmpty } from '@/utils/is'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import download from '@/utils/download'
|
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'
|
import Demo01ContactForm from './Demo01ContactForm.vue'
|
||||||
|
|
||||||
|
/** 示例联系人 列表 */
|
||||||
defineOptions({ name: 'Demo01Contact' })
|
defineOptions({ name: 'Demo01Contact' })
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref<Demo01Contact[]>([]) // 列表的数据
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
name: null,
|
name: undefined,
|
||||||
sex: null,
|
sex: undefined,
|
||||||
createTime: []
|
createTime: [],
|
||||||
})
|
})
|
||||||
const queryFormRef = ref() // 搜索的表单
|
const queryFormRef = ref() // 搜索的表单
|
||||||
const exportLoading = ref(false) // 导出的加载中
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
@ -192,6 +214,22 @@ const handleDelete = async (id: number) => {
|
||||||
} catch {}
|
} 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 () => {
|
const handleExport = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,10 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
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 { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
@ -55,13 +58,13 @@ const formData = ref({
|
||||||
name: undefined,
|
name: undefined,
|
||||||
sex: undefined,
|
sex: undefined,
|
||||||
birthday: undefined,
|
birthday: undefined,
|
||||||
description: undefined
|
description: undefined,
|
||||||
})
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
||||||
sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
|
sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
|
||||||
birthday: [{ 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
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
|
@ -91,7 +94,7 @@ const submitForm = async () => {
|
||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value as unknown as Demo03StudentApi.Demo03StudentVO
|
const data = formData.value as unknown as Demo03Student
|
||||||
if (formType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
await Demo03StudentApi.createDemo03Student(data)
|
await Demo03StudentApi.createDemo03Student(data)
|
||||||
message.success(t('common.createSuccess'))
|
message.success(t('common.createSuccess'))
|
||||||
|
|
@ -114,7 +117,7 @@ const resetForm = () => {
|
||||||
name: undefined,
|
name: undefined,
|
||||||
sex: undefined,
|
sex: undefined,
|
||||||
birthday: undefined,
|
birthday: undefined,
|
||||||
description: undefined
|
description: undefined,
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
label-width="100px"
|
label-width="100px"
|
||||||
v-loading="formLoading"
|
v-loading="formLoading"
|
||||||
>
|
>
|
||||||
<el-form-item label="名字" prop="name">
|
<el-form-item label="名字" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入名字" />
|
<el-input v-model="formData.name" placeholder="请输入名字" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="分数" prop="score">
|
<el-form-item label="分数" prop="score">
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<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 { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
@ -34,22 +34,22 @@ const formData = ref({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
studentId: undefined,
|
studentId: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
score: undefined
|
score: undefined,
|
||||||
})
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
||||||
name: [{ 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 formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
const open = async (type: string, id?: number, studentId: number) => {
|
const open = async (type: string, id?: number, studentId?: number) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
dialogTitle.value = t('action.' + type)
|
dialogTitle.value = t('action.' + type)
|
||||||
formType.value = type
|
formType.value = type
|
||||||
resetForm()
|
resetForm()
|
||||||
formData.value.studentId = studentId
|
formData.value.studentId = studentId as any
|
||||||
// 修改时,设置数据
|
// 修改时,设置数据
|
||||||
if (id) {
|
if (id) {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
|
|
@ -70,7 +70,7 @@ const submitForm = async () => {
|
||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value
|
const data = formData.value as unknown as Demo03Course
|
||||||
if (formType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
await Demo03StudentApi.createDemo03Course(data)
|
await Demo03StudentApi.createDemo03Course(data)
|
||||||
message.success(t('common.createSuccess'))
|
message.success(t('common.createSuccess'))
|
||||||
|
|
@ -92,7 +92,7 @@ const resetForm = () => {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
studentId: undefined,
|
studentId: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
score: undefined
|
score: undefined,
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,40 +2,56 @@
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['infra:demo03-student:create']"
|
|
||||||
plain
|
|
||||||
type="primary"
|
type="primary"
|
||||||
|
plain
|
||||||
@click="openForm('create')"
|
@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>
|
||||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
<el-button
|
||||||
<el-table-column align="center" label="编号" prop="id" />
|
type="danger"
|
||||||
<el-table-column align="center" label="名字" prop="name" />
|
plain
|
||||||
<el-table-column align="center" label="分数" prop="score" />
|
: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
|
<el-table-column
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="创建时间"
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
prop="createTime"
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
width="180px"
|
width="180px"
|
||||||
/>
|
/>
|
||||||
<el-table-column align="center" label="操作">
|
<el-table-column label="操作" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['infra:demo03-student:update']"
|
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['infra:demo03-student:update']"
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['infra:demo03-student:delete']"
|
|
||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="handleDelete(scope.row.id)"
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['infra:demo03-student:delete']"
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -44,19 +60,19 @@
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
v-model:page="queryParams.pageNo"
|
|
||||||
:total="total"
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<Demo03CourseForm ref="formRef" @success="getList" />
|
<Demo03CourseForm ref="formRef" @success="getList" />
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script lang="ts" setup>
|
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
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'
|
import Demo03CourseForm from './Demo03CourseForm.vue'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
@ -84,7 +100,7 @@ watch(
|
||||||
queryParams.studentId = val
|
queryParams.studentId = val
|
||||||
handleQuery()
|
handleQuery()
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true }
|
{ immediate: true, deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
/** 查询列表 */
|
/** 查询列表 */
|
||||||
|
|
@ -127,4 +143,20 @@ const handleDelete = async (id: number) => {
|
||||||
await getList()
|
await getList()
|
||||||
} catch {}
|
} 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>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
label-width="100px"
|
label-width="100px"
|
||||||
v-loading="formLoading"
|
v-loading="formLoading"
|
||||||
>
|
>
|
||||||
<el-form-item label="名字" prop="name">
|
<el-form-item label="名字" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入名字" />
|
<el-input v-model="formData.name" placeholder="请输入名字" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="班主任" prop="teacher">
|
<el-form-item label="班主任" prop="teacher">
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<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 { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
@ -34,22 +34,22 @@ const formData = ref({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
studentId: undefined,
|
studentId: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
teacher: undefined
|
teacher: undefined,
|
||||||
})
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
||||||
name: [{ 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 formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
const open = async (type: string, id?: number, studentId: number) => {
|
const open = async (type: string, id?: number, studentId?: number) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
dialogTitle.value = t('action.' + type)
|
dialogTitle.value = t('action.' + type)
|
||||||
formType.value = type
|
formType.value = type
|
||||||
resetForm()
|
resetForm()
|
||||||
formData.value.studentId = studentId
|
formData.value.studentId = studentId as any
|
||||||
// 修改时,设置数据
|
// 修改时,设置数据
|
||||||
if (id) {
|
if (id) {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
|
|
@ -70,7 +70,7 @@ const submitForm = async () => {
|
||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value
|
const data = formData.value as unknown as Demo03Grade
|
||||||
if (formType.value === 'create') {
|
if (formType.value === 'create') {
|
||||||
await Demo03StudentApi.createDemo03Grade(data)
|
await Demo03StudentApi.createDemo03Grade(data)
|
||||||
message.success(t('common.createSuccess'))
|
message.success(t('common.createSuccess'))
|
||||||
|
|
@ -92,7 +92,7 @@ const resetForm = () => {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
studentId: undefined,
|
studentId: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
teacher: undefined
|
teacher: undefined,
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,40 +2,56 @@
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['infra:demo03-student:create']"
|
|
||||||
plain
|
|
||||||
type="primary"
|
type="primary"
|
||||||
|
plain
|
||||||
@click="openForm('create')"
|
@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>
|
||||||
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
|
<el-button
|
||||||
<el-table-column align="center" label="编号" prop="id" />
|
type="danger"
|
||||||
<el-table-column align="center" label="名字" prop="name" />
|
plain
|
||||||
<el-table-column align="center" label="班主任" prop="teacher" />
|
: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
|
<el-table-column
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="创建时间"
|
label="创建时间"
|
||||||
|
align="center"
|
||||||
prop="createTime"
|
prop="createTime"
|
||||||
|
:formatter="dateFormatter"
|
||||||
width="180px"
|
width="180px"
|
||||||
/>
|
/>
|
||||||
<el-table-column align="center" label="操作">
|
<el-table-column label="操作" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['infra:demo03-student:update']"
|
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['infra:demo03-student:update']"
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['infra:demo03-student:delete']"
|
|
||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="handleDelete(scope.row.id)"
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['infra:demo03-student:delete']"
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -44,19 +60,19 @@
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
v-model:page="queryParams.pageNo"
|
|
||||||
:total="total"
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<Demo03GradeForm ref="formRef" @success="getList" />
|
<Demo03GradeForm ref="formRef" @success="getList" />
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script lang="ts" setup>
|
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
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'
|
import Demo03GradeForm from './Demo03GradeForm.vue'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
@ -84,7 +100,7 @@ watch(
|
||||||
queryParams.studentId = val
|
queryParams.studentId = val
|
||||||
handleQuery()
|
handleQuery()
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true }
|
{ immediate: true, deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
/** 查询列表 */
|
/** 查询列表 */
|
||||||
|
|
@ -127,4 +143,20 @@ const handleDelete = async (id: number) => {
|
||||||
await getList()
|
await getList()
|
||||||
} catch {}
|
} 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>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,29 @@
|
||||||
<template>
|
<template>
|
||||||
<doc-alert title="代码生成(主子表)" url="https://doc.iocoder.cn/new-feature/master-sub/" />
|
|
||||||
|
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<!-- 搜索工作栏 -->
|
<!-- 搜索工作栏 -->
|
||||||
<el-form
|
<el-form
|
||||||
|
class="-mb-15px"
|
||||||
|
:model="queryParams"
|
||||||
ref="queryFormRef"
|
ref="queryFormRef"
|
||||||
:inline="true"
|
:inline="true"
|
||||||
:model="queryParams"
|
|
||||||
class="-mb-15px"
|
|
||||||
label-width="68px"
|
label-width="68px"
|
||||||
>
|
>
|
||||||
<el-form-item label="名字" prop="name">
|
<el-form-item label="名字" prop="name">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.name"
|
v-model="queryParams.name"
|
||||||
class="!w-240px"
|
|
||||||
clearable
|
|
||||||
placeholder="请输入名字"
|
placeholder="请输入名字"
|
||||||
|
clearable
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="性别" prop="sex">
|
<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
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
|
|
@ -32,41 +35,42 @@
|
||||||
<el-form-item label="创建时间" prop="createTime">
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="queryParams.createTime"
|
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"
|
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-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery">
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
<Icon class="mr-5px" icon="ep:search" />
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
搜索
|
|
||||||
</el-button>
|
|
||||||
<el-button @click="resetQuery">
|
|
||||||
<Icon class="mr-5px" icon="ep:refresh" />
|
|
||||||
重置
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['infra:demo03-student:create']"
|
|
||||||
plain
|
|
||||||
type="primary"
|
type="primary"
|
||||||
|
plain
|
||||||
@click="openForm('create')"
|
@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>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['infra:demo03-student:export']"
|
|
||||||
:loading="exportLoading"
|
|
||||||
plain
|
|
||||||
type="success"
|
type="success"
|
||||||
|
plain
|
||||||
@click="handleExport"
|
@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-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
@ -75,50 +79,53 @@
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table
|
<el-table
|
||||||
|
row-key="id"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="list"
|
:data="list"
|
||||||
:show-overflow-tooltip="true"
|
|
||||||
:stripe="true"
|
:stripe="true"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
|
@selection-change="handleRowCheckboxChange"
|
||||||
>
|
>
|
||||||
<el-table-column align="center" label="编号" prop="id" />
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column align="center" label="名字" prop="name" />
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
<el-table-column align="center" label="性别" prop="sex">
|
<el-table-column label="名字" align="center" prop="name" />
|
||||||
|
<el-table-column label="性别" align="center" prop="sex">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
|
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="scope.row.sex" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
|
||||||
label="出生日期"
|
label="出生日期"
|
||||||
prop="birthday"
|
|
||||||
width="180px"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="简介" prop="description" />
|
|
||||||
<el-table-column
|
|
||||||
:formatter="dateFormatter"
|
|
||||||
align="center"
|
align="center"
|
||||||
label="创建时间"
|
prop="birthday"
|
||||||
prop="createTime"
|
:formatter="dateFormatter"
|
||||||
width="180px"
|
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">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['infra:demo03-student:update']"
|
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['infra:demo03-student:update']"
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPermi="['infra:demo03-student:delete']"
|
|
||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="handleDelete(scope.row.id)"
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['infra:demo03-student:delete']"
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -127,9 +134,9 @@
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
v-model:page="queryParams.pageNo"
|
|
||||||
:total="total"
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
@ -140,39 +147,41 @@
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-tabs model-value="demo03Course">
|
<el-tabs model-value="demo03Course">
|
||||||
<el-tab-pane label="学生课程" name="demo03Course">
|
<el-tab-pane label="学生课程" name="demo03Course">
|
||||||
<Demo03CourseList :student-id="currentRow?.id" />
|
<Demo03CourseList :student-id="currentRow.id" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="学生班级" name="demo03Grade">
|
<el-tab-pane label="学生班级" name="demo03Grade">
|
||||||
<Demo03GradeList :student-id="currentRow?.id" />
|
<Demo03GradeList :student-id="currentRow.id" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script setup lang="ts">
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { isEmpty } from '@/utils/is'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import download from '@/utils/download'
|
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 Demo03StudentForm from './Demo03StudentForm.vue'
|
||||||
import Demo03CourseList from './components/Demo03CourseList.vue'
|
import Demo03CourseList from './components/Demo03CourseList.vue'
|
||||||
import Demo03GradeList from './components/Demo03GradeList.vue'
|
import Demo03GradeList from './components/Demo03GradeList.vue'
|
||||||
|
|
||||||
|
/** 学生 列表 */
|
||||||
defineOptions({ name: 'Demo03Student' })
|
defineOptions({ name: 'Demo03Student' })
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref<Demo03Student[]>([]) // 列表的数据
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
name: null,
|
name: undefined,
|
||||||
sex: null,
|
sex: undefined,
|
||||||
description: null,
|
description: undefined,
|
||||||
createTime: []
|
createTime: [],
|
||||||
})
|
})
|
||||||
const queryFormRef = ref() // 搜索的表单
|
const queryFormRef = ref() // 搜索的表单
|
||||||
const exportLoading = ref(false) // 导出的加载中
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
@ -220,6 +229,22 @@ const handleDelete = async (id: number) => {
|
||||||
} catch {}
|
} 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 () => {
|
const handleExport = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -49,11 +49,14 @@
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
|
import { Demo03Student, Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
|
||||||
import Demo03CourseForm from './components/Demo03CourseForm.vue'
|
import Demo03CourseForm from './components/Demo03CourseForm.vue'
|
||||||
import Demo03GradeForm from './components/Demo03GradeForm.vue'
|
import Demo03GradeForm from './components/Demo03GradeForm.vue'
|
||||||
|
|
||||||
|
/** 学生 表单 */
|
||||||
|
defineOptions({ name: 'Demo03StudentForm' })
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
|
@ -120,7 +123,7 @@ const submitForm = async () => {
|
||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value as unknown as Demo03StudentApi.Demo03StudentVO
|
const data = formData.value as unknown as Demo03Student
|
||||||
// 拼接子表的数据
|
// 拼接子表的数据
|
||||||
data.demo03Courses = demo03CourseFormRef.value.getData()
|
data.demo03Courses = demo03CourseFormRef.value.getData()
|
||||||
data.demo03Grade = demo03GradeFormRef.value.getData()
|
data.demo03Grade = demo03GradeFormRef.value.getData()
|
||||||
|
|
|
||||||
|
|
@ -35,13 +35,13 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
|
import { Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
studentId: undefined // 学生编号(主表的关联字段)
|
studentId: number // 学生编号(主表的关联字段)
|
||||||
}>()
|
}>()
|
||||||
const formLoading = ref(false) // 表单的加载中
|
const formLoading = ref(false) // 表单的加载中
|
||||||
const formData = ref([])
|
const formData = ref<any[]>([])
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
||||||
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
||||||
|
|
@ -77,7 +77,7 @@ const handleAdd = () => {
|
||||||
name: undefined,
|
name: undefined,
|
||||||
score: undefined
|
score: undefined
|
||||||
}
|
}
|
||||||
row.studentId = props.studentId
|
row.studentId = props.studentId as any
|
||||||
formData.value.push(row)
|
formData.value.push(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<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"
|
||||||
|
>
|
||||||
<el-table-column label="编号" align="center" prop="id" />
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
<el-table-column label="名字" align="center" prop="name" />
|
<el-table-column label="名字" align="center" prop="name" />
|
||||||
<el-table-column label="分数" align="center" prop="score" />
|
<el-table-column label="分数" align="center" prop="score" />
|
||||||
|
|
@ -17,13 +23,10 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
|
import { Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
|
||||||
const message = useMessage() // 消息弹窗
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
studentId: undefined // 学生编号(主表的关联字段)
|
studentId?: number // 学生编号(主表的关联字段)
|
||||||
}>()
|
}>()
|
||||||
const loading = ref(false) // 列表的加载中
|
const loading = ref(false) // 列表的加载中
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref([]) // 列表的数据
|
||||||
|
|
@ -38,12 +41,6 @@ const getList = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
const handleQuery = () => {
|
|
||||||
queryParams.pageNo = 1
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
|
import { Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
studentId: undefined // 学生编号(主表的关联字段)
|
studentId: number // 学生编号(主表的关联字段)
|
||||||
}>()
|
}>()
|
||||||
const formLoading = ref(false) // 表单的加载中
|
const formLoading = ref(false) // 表单的加载中
|
||||||
const formData = ref([])
|
const formData = ref<any>({})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
||||||
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<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"
|
||||||
|
>
|
||||||
<el-table-column label="编号" align="center" prop="id" />
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
<el-table-column label="名字" align="center" prop="name" />
|
<el-table-column label="名字" align="center" prop="name" />
|
||||||
<el-table-column label="班主任" align="center" prop="teacher" />
|
<el-table-column label="班主任" align="center" prop="teacher" />
|
||||||
|
|
@ -17,13 +23,10 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import * as Demo03StudentApi from '@/api/infra/demo/demo03/inner'
|
import { Demo03StudentApi } from '@/api/infra/demo/demo03/inner'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
|
||||||
const message = useMessage() // 消息弹窗
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
studentId: undefined // 学生编号(主表的关联字段)
|
studentId?: number // 学生编号(主表的关联字段)
|
||||||
}>()
|
}>()
|
||||||
const loading = ref(false) // 列表的加载中
|
const loading = ref(false) // 列表的加载中
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref([]) // 列表的数据
|
||||||
|
|
@ -42,12 +45,6 @@ const getList = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
const handleQuery = () => {
|
|
||||||
queryParams.pageNo = 1
|
|
||||||
getList()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
<template>
|
<template>
|
||||||
<doc-alert title="代码生成(主子表)" url="https://doc.iocoder.cn/new-feature/master-sub/" />
|
|
||||||
|
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<!-- 搜索工作栏 -->
|
<!-- 搜索工作栏 -->
|
||||||
<el-form
|
<el-form
|
||||||
|
|
@ -37,7 +35,7 @@
|
||||||
start-placeholder="开始日期"
|
start-placeholder="开始日期"
|
||||||
end-placeholder="结束日期"
|
end-placeholder="结束日期"
|
||||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
: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>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
|
|
@ -60,13 +58,30 @@
|
||||||
>
|
>
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
</el-button>
|
</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-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<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">
|
<el-table-column type="expand">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
|
|
@ -102,7 +117,7 @@
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
width="180px"
|
width="180px"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
@ -137,28 +152,30 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<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 { dateFormatter } from '@/utils/formatTime'
|
||||||
import download from '@/utils/download'
|
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 Demo03StudentForm from './Demo03StudentForm.vue'
|
||||||
import Demo03CourseList from './components/Demo03CourseList.vue'
|
import Demo03CourseList from './components/Demo03CourseList.vue'
|
||||||
import Demo03GradeList from './components/Demo03GradeList.vue'
|
import Demo03GradeList from './components/Demo03GradeList.vue'
|
||||||
|
|
||||||
|
/** 学生 列表 */
|
||||||
defineOptions({ name: 'Demo03Student' })
|
defineOptions({ name: 'Demo03Student' })
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref<Demo03Student[]>([]) // 列表的数据
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
name: null,
|
name: undefined,
|
||||||
sex: null,
|
sex: undefined,
|
||||||
description: null,
|
description: undefined,
|
||||||
createTime: []
|
createTime: []
|
||||||
})
|
})
|
||||||
const queryFormRef = ref() // 搜索的表单
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
|
@ -207,6 +224,22 @@ const handleDelete = async (id: number) => {
|
||||||
} catch {}
|
} 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 () => {
|
const handleExport = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,13 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
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 Demo03CourseForm from './components/Demo03CourseForm.vue'
|
||||||
import Demo03GradeForm from './components/Demo03GradeForm.vue'
|
import Demo03GradeForm from './components/Demo03GradeForm.vue'
|
||||||
|
|
||||||
|
/** 学生 表单 */
|
||||||
|
defineOptions({ name: 'Demo03StudentForm' })
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
|
@ -66,13 +69,13 @@ const formData = ref({
|
||||||
name: undefined,
|
name: undefined,
|
||||||
sex: undefined,
|
sex: undefined,
|
||||||
birthday: undefined,
|
birthday: undefined,
|
||||||
description: undefined
|
description: undefined,
|
||||||
})
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
|
||||||
sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
|
sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
|
||||||
birthday: [{ 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
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
|
@ -120,7 +123,7 @@ const submitForm = async () => {
|
||||||
// 提交请求
|
// 提交请求
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value as unknown as Demo03StudentApi.Demo03StudentVO
|
const data = formData.value as unknown as Demo03Student
|
||||||
// 拼接子表的数据
|
// 拼接子表的数据
|
||||||
data.demo03Courses = demo03CourseFormRef.value.getData()
|
data.demo03Courses = demo03CourseFormRef.value.getData()
|
||||||
data.demo03Grade = demo03GradeFormRef.value.getData()
|
data.demo03Grade = demo03GradeFormRef.value.getData()
|
||||||
|
|
@ -146,7 +149,7 @@ const resetForm = () => {
|
||||||
name: undefined,
|
name: undefined,
|
||||||
sex: undefined,
|
sex: undefined,
|
||||||
birthday: undefined,
|
birthday: undefined,
|
||||||
description: undefined
|
description: undefined,
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,17 +35,17 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as Demo03StudentApi from '@/api/infra/demo/demo03/normal'
|
import { Demo03StudentApi } from '@/api/infra/demo/demo03/normal'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
studentId: undefined // 学生编号(主表的关联字段)
|
studentId: number // 学生编号(主表的关联字段)
|
||||||
}>()
|
}>()
|
||||||
const formLoading = ref(false) // 表单的加载中
|
const formLoading = ref(false) // 表单的加载中
|
||||||
const formData = ref([])
|
const formData = ref<any[]>([])
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
||||||
name: [{ 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 formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
|
@ -75,9 +75,9 @@ const handleAdd = () => {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
studentId: undefined,
|
studentId: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
score: undefined
|
score: undefined,
|
||||||
}
|
}
|
||||||
row.studentId = props.studentId
|
row.studentId = props.studentId as any
|
||||||
formData.value.push(row)
|
formData.value.push(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,17 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as Demo03StudentApi from '@/api/infra/demo/demo03/normal'
|
import { Demo03StudentApi } from '@/api/infra/demo/demo03/normal'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
studentId: undefined // 学生编号(主表的关联字段)
|
studentId: number // 学生编号(主表的关联字段)
|
||||||
}>()
|
}>()
|
||||||
const formLoading = ref(false) // 表单的加载中
|
const formLoading = ref(false) // 表单的加载中
|
||||||
const formData = ref([])
|
const formData = ref({})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
|
||||||
name: [{ 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 formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
<template>
|
<template>
|
||||||
<doc-alert title="代码生成(主子表)" url="https://doc.iocoder.cn/new-feature/master-sub/" />
|
|
||||||
|
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<!-- 搜索工作栏 -->
|
<!-- 搜索工作栏 -->
|
||||||
<el-form
|
<el-form
|
||||||
|
|
@ -20,7 +18,12 @@
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="性别" prop="sex">
|
<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
|
<el-option
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
|
|
@ -37,7 +40,7 @@
|
||||||
start-placeholder="开始日期"
|
start-placeholder="开始日期"
|
||||||
end-placeholder="结束日期"
|
end-placeholder="结束日期"
|
||||||
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
: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>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
|
|
@ -60,13 +63,30 @@
|
||||||
>
|
>
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
</el-button>
|
</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-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<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="id" />
|
||||||
<el-table-column label="名字" align="center" prop="name" />
|
<el-table-column label="名字" align="center" prop="name" />
|
||||||
<el-table-column label="性别" align="center" prop="sex">
|
<el-table-column label="性别" align="center" prop="sex">
|
||||||
|
|
@ -89,7 +109,7 @@
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
width="180px"
|
width="180px"
|
||||||
/>
|
/>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center" min-width="120px">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
|
|
@ -125,26 +145,28 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { isEmpty } from '@/utils/is'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import download from '@/utils/download'
|
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'
|
import Demo03StudentForm from './Demo03StudentForm.vue'
|
||||||
|
|
||||||
|
/** 学生 列表 */
|
||||||
defineOptions({ name: 'Demo03Student' })
|
defineOptions({ name: 'Demo03Student' })
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref<Demo03Student[]>([]) // 列表的数据
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
name: null,
|
name: undefined,
|
||||||
sex: null,
|
sex: undefined,
|
||||||
description: null,
|
description: undefined,
|
||||||
createTime: []
|
createTime: [],
|
||||||
})
|
})
|
||||||
const queryFormRef = ref() // 搜索的表单
|
const queryFormRef = ref() // 搜索的表单
|
||||||
const exportLoading = ref(false) // 导出的加载中
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
@ -192,6 +214,22 @@ const handleDelete = async (id: number) => {
|
||||||
} catch {}
|
} 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 () => {
|
const handleExport = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,24 @@ const filterNode = (name: string, data: Tree) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 处理部门被点击 */
|
/** 处理部门被点击 */
|
||||||
const handleNodeClick = async (row: { [key: string]: any }) => {
|
let currentNode: any = {}
|
||||||
emits('node-click', row)
|
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'])
|
const emits = defineEmits(['node-click'])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -255,9 +255,14 @@ const resetQuery = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 处理部门被点击 */
|
/** 处理部门被点击 */
|
||||||
const handleDeptNodeClick = async (row) => {
|
const handleDeptNodeClick = async (row: any) => {
|
||||||
queryParams.deptId = row.id
|
if (row === undefined) {
|
||||||
await getList()
|
queryParams.deptId = undefined
|
||||||
|
await getList()
|
||||||
|
} else {
|
||||||
|
queryParams.deptId = row.id
|
||||||
|
await getList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 添加/修改操作 */
|
/** 添加/修改操作 */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue