Merge branch 'master' into dev-webhook

pull/788/head
xubinbin0303 2025-06-30 17:08:36 +08:00
commit e1e3157193
86 changed files with 20010 additions and 475 deletions

View File

@ -62,16 +62,16 @@
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
@ -86,8 +86,9 @@
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
},
"editor.formatOnSave": true,
"[vue]": {
"editor.defaultFormatter": "octref.vetur"
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"i18n-ally.localesPaths": ["src/locales"],
"i18n-ally.keystyle": "nested",

17486
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@
"@wangeditor/editor-for-vue": "^5.1.10",
"@zxcvbn-ts/core": "^3.0.4",
"animate.css": "^4.1.1",
"axios": "^1.6.8",
"axios": "1.9.0",
"benz-amr-recorder": "^1.1.5",
"bpmn-js-token-simulation": "^0.36.0",
"camunda-bpmn-moddle": "^7.0.1",

View File

@ -105,3 +105,8 @@ export const createCodegenList = (data) => {
export const deleteCodegenTable = (id: number) => {
return request.delete({ url: '/infra/codegen/delete?tableId=' + id })
}
// 批量删除代码生成表定义
export const deleteCodegenTableList = (ids: number[]) => {
return request.delete({ url: '/infra/codegen/delete-list', params: { tableIds: ids.join(',') } })
}

View File

@ -42,7 +42,12 @@ export const deleteConfig = (id: number) => {
return request.delete({ url: '/infra/config/delete?id=' + id })
}
// 批量删除参数
export const deleteConfigList = (ids: number[]) => {
return request.delete({ url: '/infra/config/delete-list', params: { ids: ids.join(',') } })
}
// 导出参数
export const exportConfig = (params) => {
return request.download({ url: '/infra/config/export', params })
return request.download({ url: '/infra/config/export-excel', params })
}

View File

@ -24,6 +24,11 @@ export const deleteDataSourceConfig = (id: number) => {
return request.delete({ url: '/infra/data-source-config/delete?id=' + id })
}
// 批量删除数据源配置
export const deleteDataSourceConfigList = (ids: number[]) => {
return request.delete({ url: '/infra/data-source-config/delete-list', params: { ids: ids.join(',') } })
}
// 查询数据源配置详情
export const getDataSourceConfig = (id: number) => {
return request.get({ url: '/infra/data-source-config/get?id=' + id })

View File

@ -1,40 +1,50 @@
import request from '@/config/axios'
import type { Dayjs } from 'dayjs'
export interface Demo01ContactVO {
id: number
name: string
sex: number
birthday: Date
description: string
avatar: string
/** 示例联系人信息 */
export interface Demo01Contact {
id: number // 编号
name?: string // 名字
sex?: number // 性别
birthday?: string | Dayjs // 出生年
description?: string // 简介
avatar: string // 头像
}
// 查询示例联系人分页
export const getDemo01ContactPage = async (params) => {
return await request.get({ url: `/infra/demo01-contact/page`, params })
}
// 示例联系人 API
export const Demo01ContactApi = {
// 查询示例联系人分页
getDemo01ContactPage: async (params: any) => {
return await request.get({ url: `/infra/demo01-contact/page`, params })
},
// 查询示例联系人详情
export const getDemo01Contact = async (id: number) => {
return await request.get({ url: `/infra/demo01-contact/get?id=` + id })
}
// 查询示例联系人详情
getDemo01Contact: async (id: number) => {
return await request.get({ url: `/infra/demo01-contact/get?id=` + id })
},
// 新增示例联系人
export const createDemo01Contact = async (data: Demo01ContactVO) => {
return await request.post({ url: `/infra/demo01-contact/create`, data })
}
// 新增示例联系人
createDemo01Contact: async (data: Demo01Contact) => {
return await request.post({ url: `/infra/demo01-contact/create`, data })
},
// 修改示例联系人
export const updateDemo01Contact = async (data: Demo01ContactVO) => {
return await request.put({ url: `/infra/demo01-contact/update`, data })
}
// 修改示例联系人
updateDemo01Contact: async (data: Demo01Contact) => {
return await request.put({ url: `/infra/demo01-contact/update`, data })
},
// 删除示例联系人
export const deleteDemo01Contact = async (id: number) => {
return await request.delete({ url: `/infra/demo01-contact/delete?id=` + id })
}
// 删除示例联系人
deleteDemo01Contact: async (id: number) => {
return await request.delete({ url: `/infra/demo01-contact/delete?id=` + id })
},
// 导出示例联系人 Excel
export const exportDemo01Contact = async (params) => {
return await request.download({ url: `/infra/demo01-contact/export-excel`, params })
/** 批量删除示例联系人 */
deleteDemo01ContactList: async (ids: number[]) => {
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 })
}
}

View File

@ -1,91 +1,127 @@
import request from '@/config/axios'
import type { Dayjs } from 'dayjs';
export interface Demo03StudentVO {
id: number
name: string
sex: number
birthday: Date
description: string
/** 学生课程信息 */
export interface Demo03Course {
id: number; // 编号
studentId?: number; // 学生编号
name?: string; // 名字
score?: number; // 分数
}
// 查询学生分页
export const getDemo03StudentPage = async (params) => {
return await request.get({ url: `/infra/demo03-student/page`, params })
/** 学生班级信息 */
export interface Demo03Grade {
id: number; // 编号
studentId?: number; // 学生编号
name?: string; // 名字
teacher?: string; // 班主任
}
// 查询学生详情
export const getDemo03Student = async (id: number) => {
return await request.get({ url: `/infra/demo03-student/get?id=` + id })
/** 学生信息 */
export interface Demo03Student {
id: number; // 编号
name?: string; // 名字
sex?: number; // 性别
birthday?: string | Dayjs; // 出生日期
description?: string; // 简介
}
// 新增学生
export const createDemo03Student = async (data: Demo03StudentVO) => {
return await request.post({ url: `/infra/demo03-student/create`, data })
}
// 学生 API
export const Demo03StudentApi = {
// 查询学生分页
getDemo03StudentPage: async (params: any) => {
return await request.get({ url: `/infra/demo03-student-erp/page`, params })
},
// 修改学生
export const updateDemo03Student = async (data: Demo03StudentVO) => {
return await request.put({ url: `/infra/demo03-student/update`, data })
}
// 查询学生详情
getDemo03Student: async (id: number) => {
return await request.get({ url: `/infra/demo03-student-erp/get?id=` + id })
},
// 删除学生
export const deleteDemo03Student = async (id: number) => {
return await request.delete({ url: `/infra/demo03-student/delete?id=` + id })
}
// 新增学生
createDemo03Student: async (data: Demo03Student) => {
return await request.post({ url: `/infra/demo03-student-erp/create`, data })
},
// 导出学生 Excel
export const exportDemo03Student = async (params) => {
return await request.download({ url: `/infra/demo03-student/export-excel`, params })
}
// 修改学生
updateDemo03Student: async (data: Demo03Student) => {
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) => {
return await request.get({ url: `/infra/demo03-student/demo03-course/page`, params })
}
// 新增学生课程
export const createDemo03Course = async (data) => {
return await request.post({ url: `/infra/demo03-student/demo03-course/create`, data })
}
// 获得学生课程分页
getDemo03CoursePage: async (params) => {
return await request.get({ url: `/infra/demo03-student-erp/demo03-course/page`, params })
},
// 新增学生课程
createDemo03Course: async (data: Demo03Course) => {
return await request.post({ url: `/infra/demo03-student-erp/demo03-course/create`, data })
},
// 修改学生课程
export const updateDemo03Course = async (data) => {
return await request.put({ url: `/infra/demo03-student/demo03-course/update`, data })
}
// 修改学生课程
updateDemo03Course: async (data: Demo03Course) => {
return await request.put({ url: `/infra/demo03-student-erp/demo03-course/update`, data })
},
// 删除学生课程
export const deleteDemo03Course = async (id: number) => {
return await request.delete({ url: `/infra/demo03-student/demo03-course/delete?id=` + id })
}
// 删除学生课程
deleteDemo03Course: async (id: number) => {
return await request.delete({ url: `/infra/demo03-student-erp/demo03-course/delete?id=` + id })
},
// 获得学生课程
export const getDemo03Course = async (id: number) => {
return await request.get({ url: `/infra/demo03-student/demo03-course/get?id=` + id })
}
/** 批量删除学生课程 */
deleteDemo03CourseList: async (ids: number[]) => {
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) => {
return await request.get({ url: `/infra/demo03-student/demo03-grade/page`, params })
}
// 新增学生班级
export const createDemo03Grade = async (data) => {
return await request.post({ url: `/infra/demo03-student/demo03-grade/create`, data })
}
// 获得学生班级分页
getDemo03GradePage: async (params) => {
return await request.get({ url: `/infra/demo03-student-erp/demo03-grade/page`, params })
},
// 新增学生班级
createDemo03Grade: async (data: Demo03Grade) => {
return await request.post({ url: `/infra/demo03-student-erp/demo03-grade/create`, data })
},
// 修改学生班级
export const updateDemo03Grade = async (data) => {
return await request.put({ url: `/infra/demo03-student/demo03-grade/update`, data })
}
// 修改学生班级
updateDemo03Grade: async (data: Demo03Grade) => {
return await request.put({ url: `/infra/demo03-student-erp/demo03-grade/update`, data })
},
// 删除学生班级
export const deleteDemo03Grade = async (id: number) => {
return await request.delete({ url: `/infra/demo03-student/demo03-grade/delete?id=` + id })
}
// 删除学生班级
deleteDemo03Grade: async (id: number) => {
return await request.delete({ url: `/infra/demo03-student-erp/demo03-grade/delete?id=` + id })
},
// 获得学生班级
export const getDemo03Grade = async (id: number) => {
return await request.get({ url: `/infra/demo03-student/demo03-grade/get?id=` + id })
/** 批量删除学生班级 */
deleteDemo03GradeList: async (ids: number[]) => {
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 })
},
}

View File

@ -1,57 +1,81 @@
import request from '@/config/axios'
import type { Dayjs } from 'dayjs';
export interface Demo03StudentVO {
id: number
name: string
sex: number
birthday: Date
description: string
/** 学生课程信息 */
export interface Demo03Course {
id: number; // 编号
studentId?: number; // 学生编号
name?: string; // 名字
score?: number; // 分数
}
// 查询学生分页
export const getDemo03StudentPage = async (params) => {
return await request.get({ url: `/infra/demo03-student/page`, params })
/** 学生班级信息 */
export interface Demo03Grade {
id: number; // 编号
studentId?: number; // 学生编号
name?: string; // 名字
teacher?: string; // 班主任
}
// 查询学生详情
export const getDemo03Student = async (id: number) => {
return await request.get({ url: `/infra/demo03-student/get?id=` + id })
/** 学生信息 */
export interface Demo03Student {
id: number; // 编号
name?: string; // 名字
sex?: number; // 性别
birthday?: string | Dayjs; // 出生日期
description?: string; // 简介
demo03courses?: Demo03Course[]
demo03grade?: Demo03Grade
}
// 新增学生
export const createDemo03Student = async (data: Demo03StudentVO) => {
return await request.post({ url: `/infra/demo03-student/create`, data })
}
// 学生 API
export const Demo03StudentApi = {
// 查询学生分页
getDemo03StudentPage: async (params: any) => {
return await request.get({ url: `/infra/demo03-student-inner/page`, params })
},
// 修改学生
export const updateDemo03Student = async (data: Demo03StudentVO) => {
return await request.put({ url: `/infra/demo03-student/update`, data })
}
// 查询学生详情
getDemo03Student: async (id: number) => {
return await request.get({ url: `/infra/demo03-student-inner/get?id=` + id })
},
// 删除学生
export const deleteDemo03Student = async (id: number) => {
return await request.delete({ url: `/infra/demo03-student/delete?id=` + id })
}
// 新增学生
createDemo03Student: async (data: Demo03Student) => {
return await request.post({ url: `/infra/demo03-student-inner/create`, data })
},
// 导出学生 Excel
export const exportDemo03Student = async (params) => {
return await request.download({ url: `/infra/demo03-student/export-excel`, params })
}
// 修改学生
updateDemo03Student: async (data: Demo03Student) => {
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) => {
return await request.get({
url: `/infra/demo03-student/demo03-course/list-by-student-id?studentId=` + studentId
})
}
// 获得学生课程列表
getDemo03CourseListByStudentId: async (studentId) => {
return await request.get({ url: `/infra/demo03-student-inner/demo03-course/list-by-student-id?studentId=` + studentId })
},
// ==================== 子表(学生班级) ====================
// 获得学生班级
export const getDemo03GradeByStudentId = async (studentId) => {
return await request.get({
url: `/infra/demo03-student/demo03-grade/get-by-student-id?studentId=` + studentId
})
// 获得学生班级
getDemo03GradeByStudentId: async (studentId) => {
return await request.get({ url: `/infra/demo03-student-inner/demo03-grade/get-by-student-id?studentId=` + studentId })
},
}

View File

@ -1,57 +1,81 @@
import request from '@/config/axios'
import type { Dayjs } from 'dayjs';
export interface Demo03StudentVO {
id: number
name: string
sex: number
birthday: Date
description: string
/** 学生课程信息 */
export interface Demo03Course {
id: number; // 编号
studentId?: number; // 学生编号
name?: string; // 名字
score?: number; // 分数
}
// 查询学生分页
export const getDemo03StudentPage = async (params) => {
return await request.get({ url: `/infra/demo03-student/page`, params })
/** 学生班级信息 */
export interface Demo03Grade {
id: number; // 编号
studentId?: number; // 学生编号
name?: string; // 名字
teacher?: string; // 班主任
}
// 查询学生详情
export const getDemo03Student = async (id: number) => {
return await request.get({ url: `/infra/demo03-student/get?id=` + id })
/** 学生信息 */
export interface Demo03Student {
id: number; // 编号
name?: string; // 名字
sex?: number; // 性别
birthday?: string | Dayjs; // 出生日期
description?: string; // 简介
demo03courses?: Demo03Course[]
demo03grade?: Demo03Grade
}
// 新增学生
export const createDemo03Student = async (data: Demo03StudentVO) => {
return await request.post({ url: `/infra/demo03-student/create`, data })
}
// 学生 API
export const Demo03StudentApi = {
// 查询学生分页
getDemo03StudentPage: async (params: any) => {
return await request.get({ url: `/infra/demo03-student-normal/page`, params })
},
// 修改学生
export const updateDemo03Student = async (data: Demo03StudentVO) => {
return await request.put({ url: `/infra/demo03-student/update`, data })
}
// 查询学生详情
getDemo03Student: async (id: number) => {
return await request.get({ url: `/infra/demo03-student-normal/get?id=` + id })
},
// 删除学生
export const deleteDemo03Student = async (id: number) => {
return await request.delete({ url: `/infra/demo03-student/delete?id=` + id })
}
// 新增学生
createDemo03Student: async (data: Demo03Student) => {
return await request.post({ url: `/infra/demo03-student-normal/create`, data })
},
// 导出学生 Excel
export const exportDemo03Student = async (params) => {
return await request.download({ url: `/infra/demo03-student/export-excel`, params })
}
// 修改学生
updateDemo03Student: async (data: Demo03Student) => {
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) => {
return await request.get({
url: `/infra/demo03-student/demo03-course/list-by-student-id?studentId=` + studentId
})
}
// 获得学生课程列表
getDemo03CourseListByStudentId: async (studentId) => {
return await request.get({ url: `/infra/demo03-student-normal/demo03-course/list-by-student-id?studentId=` + studentId })
},
// ==================== 子表(学生班级) ====================
// 获得学生班级
export const getDemo03GradeByStudentId = async (studentId) => {
return await request.get({
url: `/infra/demo03-student/demo03-grade/get-by-student-id?studentId=` + studentId
})
// 获得学生班级
getDemo03GradeByStudentId: async (studentId) => {
return await request.get({ url: `/infra/demo03-student-normal/demo03-grade/get-by-student-id?studentId=` + studentId })
},
}

View File

@ -22,6 +22,11 @@ export const deleteFile = (id: number) => {
return request.delete({ url: '/infra/file/delete?id=' + id })
}
// 批量删除文件
export const deleteFileList = (ids: number[]) => {
return request.delete({ url: '/infra/file/delete-list', params: { ids: ids.join(',') } })
}
// 获取文件预签名地址
export const getFilePresignedUrl = (name: string, directory?: string) => {
return request.get<FilePresignedUrlRespVO>({

View File

@ -56,6 +56,11 @@ export const deleteFileConfig = (id: number) => {
return request.delete({ url: '/infra/file-config/delete?id=' + id })
}
// 批量删除文件配置
export const deleteFileConfigList = (ids: number[]) => {
return request.delete({ url: '/infra/file-config/delete-list', params: { ids: ids.join(',') } })
}
// 测试文件配置
export const testFileConfig = (id: number) => {
return request.get({ url: '/infra/file-config/test?id=' + id })

View File

@ -38,6 +38,11 @@ export const deleteJob = (id: number) => {
return request.delete({ url: '/infra/job/delete?id=' + id })
}
// 批量删除定时任务调度
export const deleteJobList = (ids: number[]) => {
return request.delete({ url: '/infra/job/delete-list', params: { ids: ids.join(',') } })
}
// 导出定时任务调度
export const exportJob = (params) => {
return request.download({ url: '/infra/job/export-excel', params })

View File

@ -102,7 +102,7 @@ export const deleteSpu = (id: number) => {
// 导出商品 Spu Excel
export const exportSpu = async (params: any) => {
return await request.download({ url: '/product/spu/export', params })
return await request.download({ url: '/product/spu/export-excel', params })
}
// 获得商品 SPU 精简列表

View File

@ -1,7 +1,7 @@
import request from '@/config/axios'
export interface DeptVO {
id?: number
id: number
name: string
parentId: number
status: number
@ -13,31 +13,41 @@ export interface DeptVO {
}
// 查询部门(精简)列表
export const getSimpleDeptList = async (): Promise<DeptVO[]> => {
return await request.get({ url: '/system/dept/simple-list' })
export const getSimpleDeptList = (): Promise<DeptVO[]> => {
return request.get({ url: '/system/dept/simple-list' })
}
// 查询部门列表
export const getDeptList = (params: any) => {
return request.get({ url: '/system/dept/list', params })
}
// 查询部门分页
export const getDeptPage = async (params: PageParam) => {
return await request.get({ url: '/system/dept/list', params })
}
// 查询部门详情
export const getDept = async (id: number) => {
return await request.get({ url: '/system/dept/get?id=' + id })
export const getDept = (id: number) => {
return request.get({ url: '/system/dept/get?id=' + id })
}
// 新增部门
export const createDept = async (data: DeptVO) => {
return await request.post({ url: '/system/dept/create', data: data })
export const createDept = (data: DeptVO) => {
return request.post({ url: '/system/dept/create', data })
}
// 修改部门
export const updateDept = async (params: DeptVO) => {
return await request.put({ url: '/system/dept/update', data: params })
export const updateDept = (data: DeptVO) => {
return request.put({ url: '/system/dept/update', data })
}
// 删除部门
export const deleteDept = async (id: number) => {
return await request.delete({ url: '/system/dept/delete?id=' + id })
}
// 批量删除部门
export const deleteDeptList = async (ids: number[]) => {
return await request.delete({ url: '/system/dept/delete-list', params: { ids: ids.join(',') } })
}

View File

@ -1,8 +1,8 @@
import request from '@/config/axios'
export type DictDataVO = {
id: number | undefined
sort: number | undefined
export interface DictDataVO {
id: number
sort: number
label: string
value: string
dictType: string
@ -28,6 +28,11 @@ export const getDictData = (id: number) => {
return request.get({ url: '/system/dict-data/get?id=' + id })
}
// 根据字典类型查询字典数据
export const getDictDataByType = (dictType: string) => {
return request.get({ url: '/system/dict-data/type?type=' + dictType })
}
// 新增字典数据
export const createDictData = (data: DictDataVO) => {
return request.post({ url: '/system/dict-data/create', data })
@ -43,7 +48,12 @@ export const deleteDictData = (id: number) => {
return request.delete({ url: '/system/dict-data/delete?id=' + id })
}
// 导出字典类型数据
export const exportDictData = (params) => {
return request.download({ url: '/system/dict-data/export', params })
// 批量删除字典数据
export const deleteDictDataList = (ids: number[]) => {
return request.delete({ url: '/system/dict-data/delete-list', params: { ids: ids.join(',') } })
}
// 导出字典数据
export const exportDictData = (params: any) => {
return request.download({ url: '/system/dict-data/export-excel', params })
}

View File

@ -1,7 +1,7 @@
import request from '@/config/axios'
export type DictTypeVO = {
id: number | undefined
export interface DictTypeVO {
id: number
name: string
type: string
status: number
@ -10,8 +10,8 @@ export type DictTypeVO = {
}
// 查询字典(精简)列表
export const getSimpleDictTypeList = () => {
return request.get({ url: '/system/dict-type/list-all-simple' })
export const getSimpleDictTypeList = (): Promise<DictTypeVO[]> => {
return request.get({ url: '/system/dict-type/simple-list' })
}
// 查询字典列表
@ -38,7 +38,16 @@ export const updateDictType = (data: DictTypeVO) => {
export const deleteDictType = (id: number) => {
return request.delete({ url: '/system/dict-type/delete?id=' + id })
}
// 导出字典类型
export const exportDictType = (params) => {
return request.download({ url: '/system/dict-type/export', params })
// 批量删除字典类型
export const deleteDictTypeList = (ids: number[]) => {
return request.delete({ url: '/system/dict-type/delete-list', params: { ids: ids.join(',') } })
}
// 导出字典
export const exportDictType = (params) => {
return request.download({
url: '/system/dict-type/export-excel',
params
})
}

View File

@ -21,5 +21,5 @@ export const getLoginLogPage = (params: PageParam) => {
// 导出登录日志
export const exportLoginLog = (params) => {
return request.download({ url: '/system/login-log/export', params })
return request.download({ url: '/system/login-log/export-excel', params })
}

View File

@ -36,6 +36,11 @@ export const deleteMailAccount = async (id: number) => {
return await request.delete({ url: '/system/mail-account/delete?id=' + id })
}
// 批量删除邮箱账号
export const deleteMailAccountList = async (ids: number[]) => {
return await request.delete({ url: '/system/mail-account/delete-list', params: { ids: ids.join(',') } })
}
// 获得邮箱账号精简列表
export const getSimpleMailAccountList = async () => {
return request.get({ url: '/system/mail-account/simple-list' })

View File

@ -44,6 +44,11 @@ export const deleteMailTemplate = async (id: number) => {
return await request.delete({ url: '/system/mail-template/delete?id=' + id })
}
// 批量删除邮件模版
export const deleteMailTemplateList = async (ids: number[]) => {
return await request.delete({ url: '/system/mail-template/delete-list', params: { ids: ids.join(',') } })
}
// 发送邮件
export const sendMail = (data: MailSendReqVO) => {
return request.post({ url: '/system/mail-template/send-mail', data })

View File

@ -36,6 +36,11 @@ export const deleteNotice = (id: number) => {
return request.delete({ url: '/system/notice/delete?id=' + id })
}
// 批量删除公告
export const deleteNoticeList = (ids: number[]) => {
return request.delete({ url: '/system/notice/delete-list', params: { ids: ids.join(',') } })
}
// 推送公告
export const pushNotice = (id: number) => {
return request.post({ url: '/system/notice/push?id=' + id })

View File

@ -43,6 +43,11 @@ export const deleteNotifyTemplate = async (id: number) => {
return await request.delete({ url: '/system/notify-template/delete?id=' + id })
}
// 批量删除站内信模板
export const deleteNotifyTemplateList = async (ids: number[]) => {
return await request.delete({ url: '/system/notify-template/delete-list', params: { ids: ids.join(',') } })
}
// 发送站内信
export const sendNotify = (data: NotifySendReqVO) => {
return request.post({ url: '/system/notify-template/send-notify', data })

View File

@ -45,3 +45,8 @@ export const updateOAuth2Client = (data: OAuth2ClientVO) => {
export const deleteOAuth2Client = (id: number) => {
return request.delete({ url: '/system/oauth2-client/delete?id=' + id })
}
// 批量删除 OAuth2 客户端
export const deleteOAuth2ClientList = (ids: number[]) => {
return request.delete({ url: '/system/oauth2-client/delete-list', params: { ids: ids.join(',') } })
}

View File

@ -26,5 +26,5 @@ export const getOperateLogPage = (params: PageParam) => {
}
// 导出操作日志
export const exportOperateLog = (params: any) => {
return request.download({ url: '/system/operate-log/export', params })
return request.download({ url: '/system/operate-log/export-excel', params })
}

View File

@ -40,7 +40,12 @@ export const deletePost = async (id: number) => {
return await request.delete({ url: '/system/post/delete?id=' + id })
}
// 批量删除岗位
export const deletePostList = async (ids: number[]) => {
return await request.delete({ url: '/system/post/delete-list', params: { ids: ids.join(',') } })
}
// 导出岗位
export const exportPost = async (params) => {
return await request.download({ url: '/system/post/export', params })
return await request.download({ url: '/system/post/export-excel', params })
}

View File

@ -52,6 +52,11 @@ export const deleteRole = async (id: number) => {
return await request.delete({ url: '/system/role/delete?id=' + id })
}
// 批量删除角色
export const deleteRoleList = async (ids: number[]) => {
return await request.delete({ url: '/system/role/delete-list', params: { ids: ids.join(',') } })
}
// 导出角色
export const exportRole = (params) => {
return request.download({

View File

@ -41,3 +41,8 @@ export const updateSmsChannel = (data: SmsChannelVO) => {
export const deleteSmsChannel = (id: number) => {
return request.delete({ url: '/system/sms-channel/delete?id=' + id })
}
// 批量删除短信渠道
export const deleteSmsChannelList = (ids: number[]) => {
return request.delete({ url: '/system/sms-channel/delete-list', params: { ids: ids.join(',') } })
}

View File

@ -46,6 +46,11 @@ export const deleteSmsTemplate = (id: number) => {
return request.delete({ url: '/system/sms-template/delete?id=' + id })
}
// 批量删除短信模板
export const deleteSmsTemplateList = (ids: number[]) => {
return request.delete({ url: '/system/sms-template/delete-list', params: { ids: ids.join(',') } })
}
// 导出短信模板
export const exportSmsTemplate = (params) => {
return request.download({

View File

@ -61,6 +61,11 @@ export const deleteTenant = (id: number) => {
return request.delete({ url: '/system/tenant/delete?id=' + id })
}
// 批量删除租户
export const deleteTenantList = (ids: number[]) => {
return request.delete({ url: '/system/tenant/delete-list', params: { ids: ids.join(',') } })
}
// 导出租户
export const exportTenant = (params: TenantExportReqVO) => {
return request.download({ url: '/system/tenant/export-excel', params })

View File

@ -36,6 +36,12 @@ export const updateTenantPackage = (data: TenantPackageVO) => {
export const deleteTenantPackage = (id: number) => {
return request.delete({ url: '/system/tenant-package/delete?id=' + id })
}
// 批量删除租户套餐
export const deleteTenantPackageList = (ids: number[]) => {
return request.delete({ url: '/system/tenant-package/delete-list', params: { ids: ids.join(',') } })
}
// 获取租户套餐精简信息列表
export const getTenantPackageList = () => {
return request.get({ url: '/system/tenant-package/simple-list' })

View File

@ -42,9 +42,14 @@ export const deleteUser = (id: number) => {
return request.delete({ url: '/system/user/delete?id=' + id })
}
// 批量删除用户
export const deleteUserList = (ids: number[]) => {
return request.delete({ url: '/system/user/delete-list', params: { ids: ids.join(',') } })
}
// 导出用户
export const exportUser = (params: any) => {
return request.download({ url: '/system/user/export', params })
return request.download({ url: '/system/user/export-excel', params })
}
// 下载用户导入模板

View File

@ -1,9 +1,11 @@
<script lang="ts" setup>
import { propTypes } from '@/utils/propTypes'
import { isNumber } from '@/utils/is'
defineOptions({ name: 'Dialog' })
const slots = useSlots()
const emits = defineEmits(['update:modelValue'])
const props = defineProps({
modelValue: propTypes.bool.def(false),
@ -55,6 +57,17 @@ const dialogStyle = computed(() => {
height: unref(dialogHeight)
}
})
const closing = ref(false)
function closeHandler() {
emits('update:modelValue', false)
closing.value = true
}
function closedHandler() {
closing.value = false
}
</script>
<template>
@ -68,7 +81,8 @@ const dialogStyle = computed(() => {
draggable
class="com-dialog"
:show-close="false"
@close="$emit('update:modelValue', false)"
@close="closeHandler"
@closed="closedHandler"
>
<template #header="{ close }">
<div class="relative h-54px flex items-center justify-between pl-15px pr-15px">
@ -102,7 +116,9 @@ const dialogStyle = computed(() => {
</ElScrollbar>
<slot v-else></slot>
<template v-if="slots.footer" #footer>
<slot name="footer"></slot>
<div :style="{ 'pointer-events': closing ? 'none' : 'auto' }">
<slot name="footer"></slot>
</div>
</template>
</ElDialog>
</template>

View File

@ -10,6 +10,8 @@ export interface CarouselProperty {
autoplay: boolean
// 播放间隔
interval: number
// 轮播高度
height: number
// 轮播内容
items: CarouselItemProperty[]
// 组件样式
@ -37,6 +39,7 @@ export const component = {
indicator: 'dot',
autoplay: false,
interval: 3,
height: 174,
items: [
{ type: 'img', imgUrl: 'https://static.iocoder.cn/mall/banner-01.jpg', videoUrl: '' },
{ type: 'img', imgUrl: 'https://static.iocoder.cn/mall/banner-02.jpg', videoUrl: '' }

View File

@ -8,7 +8,7 @@
</div>
<div v-else class="relative">
<el-carousel
height="174px"
:height="property.height + 'px'"
:type="property.type === 'card' ? 'card' : ''"
:autoplay="property.autoplay"
:interval="property.interval * 1000"

View File

@ -16,6 +16,9 @@
</el-tooltip>
</el-radio-group>
</el-form-item>
<el-form-item label="高度" prop="height">
<el-input-number class="!w-50% mr-10px" controls-position="right" v-model="formData.height" /> px
</el-form-item>
<el-form-item label="指示器" prop="indicator">
<el-radio-group v-model="formData.indicator">
<el-radio value="dot">小圆点</el-radio>

View File

@ -23,22 +23,20 @@
export default function customTranslate(translations) {
return function (template, replacements) {
replacements = replacements || {}
// Translate
template = translations[template] || template
replacements = replacements || {};
// 将模板和翻译字典的键统一转换为小写进行匹配
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) {
let str = replacements[key]
if (
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 + '}'
})
}
}
// 如果替换值存在,返回替换值;否则返回原始占位符
return replacements[key] !== undefined ? replacements[key] : `{${key}}`;
});
};
}

View File

@ -45,8 +45,8 @@ export default {
'Service Task': '服务任务',
'Script Task': '脚本任务',
'Call Activity': '调用活动',
'Sub Process (collapsed)': '子流程(折叠的)',
'Sub Process (expanded)': '子流程(展开的)',
'Sub-Process (collapsed)': '子流程(折叠的)',
'Sub-Process (expanded)': '子流程(展开的)',
'Start Event': '开始事件',
StartEvent: '开始事件',
'Intermediate Throw Event': '中间事件',

View File

@ -68,6 +68,11 @@
:business-object="elementBusinessObject"
/>
</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>
</div>
</template>
@ -83,6 +88,8 @@ import ElementProperties from './properties/ElementProperties.vue'
// import ElementForm from './form/ElementForm.vue'
import UserTaskListeners from './listeners/UserTaskListeners.vue'
import { getTaskCollapseItemName, isTaskCollapseItemShow } from './task/data'
import TimeEventConfig from './time-event-config/TimeEventConfig.vue'
import { ref, watch, onMounted } from 'vue'
defineOptions({ name: 'MyPropertiesPanel' })
@ -121,6 +128,8 @@ const formVisible = ref(false) // 表单配置
const bpmnElement = ref()
const isReady = ref(false)
const type = ref('time')
const condition = ref('')
provide('prefix', props.prefix)
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) {
const w = window as any
w.bpmnInstances = instances
@ -255,4 +264,48 @@ watch(
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>

View File

@ -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] || '*'
})
// weekyear
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>

View File

@ -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 8601custom
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>

View File

@ -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>

View File

@ -12,7 +12,7 @@ const router = createRouter({
})
export const resetRouter = (): void => {
const resetWhiteNameList = ['Redirect', 'Login', 'NoFind', 'Root']
const resetWhiteNameList = ['Redirect', 'Login', 'NoFound', 'Home']
router.getRoutes().forEach((route) => {
const { name } = route
if (name && !resetWhiteNameList.includes(name as string)) {

View File

@ -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 { ElementPlusSize } from '@/types/elementPlus'
import { LayoutType } from '@/types/layout'
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()
@ -183,6 +184,40 @@ export const useAppStore = defineStore('app', {
}
},
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) {
this.breadcrumb = breadcrumb
},
@ -256,6 +291,7 @@ export const useAppStore = defineStore('app', {
document.documentElement.classList.remove('dark')
}
wsCache.set(CACHE_KEY.IS_DARK, this.isDark)
this.setPrimaryLight()
},
setCurrentSize(currentSize: ElementPlusSize) {
this.currentSize = currentSize
@ -272,6 +308,7 @@ export const useAppStore = defineStore('app', {
for (const key in this.theme) {
setCssVar(`--${humpToUnderline(key)}`, this.theme[key])
}
this.setPrimaryLight()
},
setFooter(footer: boolean) {
this.footer = footer

View File

@ -172,3 +172,46 @@ export const PREDEFINE_COLORS = [
'#1f73c3',
'#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 ''
}

View File

@ -1,6 +1,7 @@
/**
* https://github.com/xaboy/form-create-designer 封装的工具类
*/
import { isRef } from 'vue'
// 编码表单 Conf
export const encodeConf = (designerRef: object) => {
@ -47,10 +48,182 @@ export const setConfAndFields2 = (
// @ts-ignore
detailPreview = detailPreview.value
}
// 解析配置
const option = JSON.parse(conf)
const rule = decodeFields(fields)
// 🔧 修复所有函数类型 - 解决设计器保存后函数变成字符串的问题
const fixFunctions = (obj: any) => {
if (obj && typeof obj === 'object') {
Object.keys(obj).forEach(key => {
// 检查是否是函数相关的属性
if (isFunctionProperty(key)) {
// 如果不是函数类型,重新构建为函数
if (typeof obj[key] !== 'function') {
obj[key] = createDefaultFunction(key)
}
} else if (typeof obj[key] === 'object' && obj[key] !== null) {
// 递归处理嵌套对象
fixFunctions(obj[key])
}
})
}
}
// 判断是否是函数属性
const isFunctionProperty = (key: string): boolean => {
const functionKeys = [
'beforeFetch', // 请求前处理
'afterFetch', // 请求后处理
'onSubmit', // 表单提交
'onReset', // 表单重置
'onChange', // 值变化
'onInput', // 输入事件
'onClick', // 点击事件
'onFocus', // 获取焦点
'onBlur', // 失去焦点
'onMounted', // 组件挂载
'onCreated', // 组件创建
'onReload', // 重新加载
'remoteMethod', // 远程搜索方法
'parseFunc', // 解析函数
'validator', // 验证器
'asyncValidator', // 异步验证器
'formatter', // 格式化函数
'parser', // 解析函数
'beforeUpload', // 上传前处理
'onSuccess', // 成功回调
'onError', // 错误回调
'onProgress', // 进度回调
'onPreview', // 预览回调
'onRemove', // 移除回调
'onExceed', // 超出限制回调
'filterMethod', // 过滤方法
'sortMethod', // 排序方法
'loadData', // 加载数据
'renderContent', // 渲染内容
'render' // 渲染函数
]
// 检查是否以函数相关前缀开头
const functionPrefixes = ['on', 'before', 'after', 'handle']
return functionKeys.includes(key) ||
functionPrefixes.some(prefix => key.startsWith(prefix))
}
// 根据函数名创建默认函数
const createDefaultFunction = (key: string): Function => {
switch (key) {
case 'beforeFetch':
return (config: any) => {
console.log('beforeFetch被调用:', config)
// 添加认证头
const token = localStorage.getItem('token')
if (token) {
config.headers = {
...config.headers,
'Authorization': 'Bearer ' + token
}
}
// 添加通用请求头
config.headers = {
...config.headers,
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
}
// 添加时间戳防止缓存
config.params = {
...config.params,
_t: Date.now()
}
return config
}
case 'afterFetch':
return (data: any) => {
console.log('afterFetch被调用:', data)
return data
}
case 'onSubmit':
return (formData: any) => {
console.log('onSubmit被调用:', formData)
return true
}
case 'onReset':
return () => {
console.log('onReset被调用')
return true
}
case 'onChange':
return (value: any, oldValue: any) => {
console.log('onChange被调用:', { value, oldValue })
}
case 'remoteMethod':
return (query: string) => {
console.log('remoteMethod被调用:', query)
}
case 'parseFunc':
return (data: any) => {
console.log('parseFunc被调用:', data)
// 默认解析逻辑如果是数组直接返回否则尝试获取list属性
if (Array.isArray(data)) {
return data
}
return data?.list || data?.data || []
}
case 'validator':
return (rule: any, value: any, callback: Function) => {
console.log('validator被调用:', { rule, value })
callback()
}
case 'beforeUpload':
return (file: any) => {
console.log('beforeUpload被调用:', file)
return true
}
default:
// 通用默认函数
return (...args: any[]) => {
console.log(`${key}被调用:`, args)
// 对于事件处理函数返回true表示继续执行
if (key.startsWith('on') || key.startsWith('handle')) {
return true
}
// 对于其他函数,返回第一个参数(通常是数据传递)
return args[0]
}
}
}
// 修复option中的所有函数
fixFunctions(option)
// 修复rule中的所有函数包括组件的props
if (Array.isArray(rule)) {
rule.forEach((item: any) => {
fixFunctions(item)
})
}
// @ts-ignore
detailPreview.option = JSON.parse(conf)
detailPreview.option = option
// @ts-ignore
detailPreview.rule = decodeFields(fields)
detailPreview.rule = rule
if (value) {
// @ts-ignore
detailPreview.value = value

View File

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

View File

@ -55,13 +55,23 @@
<Icon class="mr-5px" icon="ep:zoom-in" />
导入
</el-button>
<el-button
v-hasPermi="['infra:codegen:delete']"
type="danger"
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
>
<Icon class="mr-5px" icon="ep:delete" />
批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
<el-table-column type="selection" width="55" />
<el-table-column align="center" label="数据源">
<template #default="scope">
{{
@ -232,6 +242,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: CodegenApi.CodegenTableVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await CodegenApi.deleteCodegenTableList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 同步操作 */
const handleSyncDB = async (row: CodegenApi.CodegenTableVO) => {
// DB

View File

@ -65,6 +65,15 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['infra:config:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
<el-button
type="success"
plain
@ -80,7 +89,8 @@
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @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="category" />
<el-table-column label="参数名称" align="center" prop="name" :show-overflow-tooltip="true" />
@ -206,6 +216,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: ConfigApi.ConfigVO[]) => {
checkedIds.value = rows.map((row) => row.id!).filter(Boolean)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await ConfigApi.deleteConfigList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

View File

@ -11,13 +11,23 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['infra:data-source-config:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @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="url" :show-overflow-tooltip="true" />
@ -99,6 +109,25 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: DataSourceConfigApi.DataSourceConfigVO[]) => {
// id 0
checkedIds.value = rows.map((row) => row.id!).filter((id) => id !== 0 && Boolean(id))
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await DataSourceConfigApi.deleteDataSourceConfigList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 初始化 **/
onMounted(() => {
getList()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -44,13 +44,23 @@
<el-button type="primary" plain @click="openForm">
<Icon icon="ep:upload" class="mr-5px" /> 上传文件
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['infra:file:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
<el-table-column type="selection" width="55" />
<el-table-column label="文件名" align="center" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="文件路径" align="center" prop="path" :show-overflow-tooltip="true" />
<el-table-column label="URL" align="center" prop="url" :show-overflow-tooltip="true" />
@ -195,6 +205,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await FileApi.deleteFileList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 初始化 **/
onMounted(() => {
getList()

View File

@ -56,13 +56,23 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['infra:file-config:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @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="storage">
@ -192,6 +202,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await FileConfigApi.deleteFileConfigList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 主配置按钮操作 */
const handleMaster = async (id) => {
try {

View File

@ -56,6 +56,15 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['infra:job:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
<el-button
type="success"
plain
@ -74,7 +83,8 @@
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @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="status">
@ -251,6 +261,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: JobApi.JobVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await JobApi.deleteJobList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** '更多'操作按钮 */
const handleCommand = (command, row) => {
switch (command) {

View File

@ -46,6 +46,15 @@
<el-button type="danger" plain @click="toggleExpandAll">
<Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:dept:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
@ -58,7 +67,9 @@
row-key="id"
:default-expand-all="isExpandAll"
v-if="refreshTable"
@selection-change="handleRowCheckboxChange"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="name" label="部门名称" />
<el-table-column prop="leader" label="负责人">
<template #default="scope">
@ -181,6 +192,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: DeptApi.DeptVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await DeptApi.deleteDeptList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 初始化 **/
onMounted(async () => {
await getList()

View File

@ -56,13 +56,23 @@
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:dict:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @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="label" />
<el-table-column label="字典键值" align="center" prop="value" />
@ -186,6 +196,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: DictDataApi.DictDataVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await DictDataApi.deleteDictDataList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

View File

@ -80,13 +80,24 @@
<Icon class="mr-5px" icon="ep:download" />
导出
</el-button>
<el-button
v-hasPermi="['system:dict:delete']"
:disabled="checkedIds.length === 0"
plain
type="danger"
@click="handleDeleteBatch"
>
<Icon class="mr-5px" icon="ep:delete" />
批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
<el-table-column type="selection" width="55" />
<el-table-column align="center" label="字典编号" prop="id" />
<el-table-column align="center" label="字典名称" prop="name" show-overflow-tooltip />
<el-table-column align="center" label="字典类型" prop="type" width="300" />
@ -209,6 +220,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: DictTypeApi.DictTypeVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await DictTypeApi.deleteDictTypeList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

View File

@ -14,6 +14,15 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="danger"
plain
@click="handleDeleteBatch"
:disabled="!isSelected"
v-hasPermi="['system:mail-account:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</template>
</Search>
</ContentWrap>
@ -29,6 +38,7 @@
}"
v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage"
:selection="true"
>
<template #action="{ row }">
<el-button
@ -99,6 +109,19 @@ const handleDelete = (id: number) => {
tableMethods.delList(id, false)
}
/** 是否有选中行 */
const isSelected = computed(() => {
return tableObject.selections && tableObject.selections.length > 0
})
/** 批量删除按钮操作 */
const handleDeleteBatch = async () => {
const ids = tableObject.selections.map(item => item.id)
if (ids.length === 0) return
await MailAccountApi.deleteMailAccountList(ids)
tableMethods.getList()
}
/** 初始化 **/
onMounted(() => {
getList()

View File

@ -14,6 +14,15 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="danger"
plain
@click="handleDeleteBatch"
:disabled="!isSelected"
v-hasPermi="['system:mail-template:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</template>
</Search>
</ContentWrap>
@ -29,6 +38,7 @@
}"
v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage"
:selection="true"
>
<template #action="{ row }">
<el-button
@ -94,6 +104,19 @@ const handleDelete = (id: number) => {
tableMethods.delList(id, false)
}
/** 是否有选中行 */
const isSelected = computed(() => {
return tableObject.selections && tableObject.selections.length > 0
})
/** 批量删除按钮操作 */
const handleDeleteBatch = async () => {
const ids = tableObject.selections.map(item => item.id)
if (ids.length === 0) return
await MailTemplateApi.deleteMailTemplateList(ids)
tableMethods.getList()
}
/** 发送测试操作 */
const sendFormRef = ref()
const openSendForm = (id: number) => {

View File

@ -43,13 +43,23 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:notice:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @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="title" />
<el-table-column label="公告类型" align="center" prop="type">
@ -171,6 +181,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: NoticeApi.NoticeVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await NoticeApi.deleteNoticeList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 推送按钮操作 */
const handlePush = async (id: number) => {
try {

View File

@ -65,13 +65,23 @@
>
<Icon icon="ep:plus" class="mr-5px" />新增
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:notify-template:delete']"
>
<Icon icon="ep:delete" class="mr-5px" />批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
<el-table-column type="selection" width="55" />
<el-table-column
label="模板编码"
align="center"
@ -165,6 +175,7 @@ import NotifyTemplateSendForm from './NotifyTemplateSendForm.vue'
defineOptions({ name: 'NotifySmsTemplate' })
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(false) //
const total = ref(0) //
@ -216,7 +227,25 @@ const handleDelete = async (id: number) => {
await message.delConfirm()
//
await NotifyTemplateApi.deleteNotifyTemplate(id)
message.success('删除成功')
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: NotifyTemplateApi.NotifyTemplateVO[]) => {
checkedIds.value = rows.map((row) => row.id!)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await NotifyTemplateApi.deleteNotifyTemplateList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}

View File

@ -40,13 +40,23 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
plain
type="danger"
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:oauth2-client:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
<el-table-column type="selection" width="55" />
<el-table-column label="客户端编号" align="center" prop="clientId" />
<el-table-column label="客户端密钥" align="center" prop="secret" />
<el-table-column label="应用名" align="center" prop="name" />
@ -184,6 +194,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: ClientApi.OAuth2ClientVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await ClientApi.deleteOAuth2ClientList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 初始化 **/
onMounted(() => {
getList()

View File

@ -56,13 +56,23 @@
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:post:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @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="code" />
@ -181,6 +191,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: PostApi.PostVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await PostApi.deletePostList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

View File

@ -78,13 +78,24 @@
<Icon class="mr-5px" icon="ep:download" />
导出
</el-button>
<el-button
v-hasPermi="['system:role:delete']"
:disabled="checkedIds.length === 0"
plain
type="danger"
@click="handleDeleteBatch"
>
<Icon class="mr-5px" icon="ep:delete" />
批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
<el-table-column type="selection" width="55" />
<el-table-column align="center" label="角色编号" prop="id" />
<el-table-column align="center" label="角色名称" prop="name" />
<el-table-column label="角色类型" align="center" prop="type">
@ -247,6 +258,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: RoleApi.RoleVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await RoleApi.deleteRoleList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
@ -255,14 +284,14 @@ const handleExport = async () => {
//
exportLoading.value = true
const data = await RoleApi.exportRole(queryParams)
download.excel(data, '角色列表.xls')
download.excel(data, '角色数据.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
/** 初始化 */
onMounted(() => {
getList()
})

View File

@ -55,13 +55,23 @@
>
<Icon icon="ep:plus" class="mr-5px" /> 新增</el-button
>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:sms-channel:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除</el-button
>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @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="signature" />
<el-table-column label="渠道编码" align="center" prop="code">
@ -202,6 +212,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: SmsChannelApi.SmsChannelVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await SmsChannelApi.deleteSmsChannelList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 初始化 **/
onMounted(() => {
getList()

View File

@ -98,6 +98,15 @@
>
<Icon icon="ep:plus" class="mr-5px" />新增
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:sms-template:delete']"
>
<Icon icon="ep:delete" class="mr-5px" />批量删除
</el-button>
<el-button
type="success"
plain
@ -113,7 +122,8 @@
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
<el-table-column type="selection" width="55" />
<el-table-column
label="模板编码"
align="center"
@ -292,6 +302,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: SmsTemplateApi.SmsTemplateVO[]) => {
checkedIds.value = rows.map((row) => row.id!)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await SmsTemplateApi.deleteSmsTemplateList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

View File

@ -92,13 +92,24 @@
<Icon icon="ep:download" class="mr-5px" />
导出
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:tenant:delete']"
>
<Icon icon="ep:delete" class="mr-5px" />
批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @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="packageId">
@ -243,6 +254,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: TenantApi.TenantVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await TenantApi.deleteTenantList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
@ -261,6 +290,7 @@ const handleExport = async () => {
/** 初始化 **/
onMounted(async () => {
await getList()
//
packageList.value = await TenantPackageApi.getTenantPackageList()
})
</script>

View File

@ -51,13 +51,24 @@
<Icon icon="ep:plus" class="mr-5px" />
新增
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:tenant-package:delete']"
>
<Icon icon="ep:delete" class="mr-5px" />
批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
<el-table-column type="selection" width="55" />
<el-table-column label="套餐编号" align="center" prop="id" width="120" />
<el-table-column label="套餐名" align="center" prop="name" />
<el-table-column label="状态" align="center" prop="status" width="100">
@ -173,6 +184,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: TenantPackageApi.TenantPackageVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await TenantPackageApi.deleteTenantPackageList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 初始化 **/
onMounted(() => {
getList()

View File

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

View File

@ -91,11 +91,21 @@
>
<Icon icon="ep:download" />导出
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:user:delete']"
>
<Icon icon="ep:delete" />批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
<el-table-column type="selection" width="55" />
<el-table-column label="用户编号" align="center" key="id" prop="id" />
<el-table-column
label="用户名称"
@ -255,9 +265,14 @@ const resetQuery = () => {
}
/** 处理部门被点击 */
const handleDeptNodeClick = async (row) => {
queryParams.deptId = row.id
await getList()
const handleDeptNodeClick = async (row: any) => {
if (row === undefined) {
queryParams.deptId = undefined
await getList()
} else {
queryParams.deptId = row.id
await getList()
}
}
/** 添加/修改操作 */
@ -335,6 +350,24 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: UserApi.UserVO[]) => {
checkedIds.value = rows.map((row) => row.id)
}
const handleDeleteBatch = async () => {
try {
//
await message.delConfirm()
//
await UserApi.deleteUserList(checkedIds.value)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 重置密码 */
const handleResetPwd = async (row: UserApi.UserVO) => {
try {