准备验证
This commit is contained in:
68
src/api/ems/qualityReport.ts
Normal file
68
src/api/ems/qualityReport.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询素质报告单列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/ems/emsqualityreport/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑评语
|
||||
* @param data
|
||||
*/
|
||||
export const updatePY = (data: any) => {
|
||||
return request({
|
||||
url: '/ems/emsqualityreport/updatePY',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 评语导入
|
||||
* @param file
|
||||
*/
|
||||
export const importComment = (file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return request({
|
||||
url: '/ems/emsqualityreport/importComment',
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置班级开学时间
|
||||
* @param data
|
||||
*/
|
||||
export const setClassStartTime = (data: any) => {
|
||||
return request({
|
||||
url: '/ems/emsqualityreport/setClassStartTime',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 名单导出
|
||||
* @param query
|
||||
*/
|
||||
export const exportExcel = (query?: any) => {
|
||||
return request({
|
||||
url: '/ems/emsqualityreport/exportExcel',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob' // Important for file downloads
|
||||
});
|
||||
};
|
||||
|
||||
88
src/api/stuwork/activityawards.ts
Normal file
88
src/api/stuwork/activityawards.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询获奖活动信息列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/activityawards/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增获奖活动信息
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/activityawards',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: `/stuwork/activityawards/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑获奖活动信息
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/activityawards',
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除获奖活动信息
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/activityawards',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取活动主题列表
|
||||
*/
|
||||
export const getActivityInfoList = () => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfo/activityInfoList',
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导入获奖活动信息
|
||||
* @param file 文件
|
||||
*/
|
||||
export const importExcel = (file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return request({
|
||||
url: '/stuwork/activityawards/import',
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
79
src/api/stuwork/activityinfo.ts
Normal file
79
src/api/stuwork/activityinfo.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询活动列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfo/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增活动
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfo',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: `/stuwork/activityinfo/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑活动
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfo',
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除活动
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfo',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导入子项目
|
||||
* @param id 活动ID
|
||||
* @param file 文件
|
||||
*/
|
||||
export const importSub = (id: string, file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return request({
|
||||
url: `/stuwork/activityinfo/importSub/${id}`,
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
36
src/api/stuwork/activityinfosub.ts
Normal file
36
src/api/stuwork/activityinfosub.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询活动子项目列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfosub/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取活动主题列表
|
||||
*/
|
||||
export const getActivityInfoList = () => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfo/activityInfoList',
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除活动子项目
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfosub',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
61
src/api/stuwork/activityinfosubsignup.ts
Normal file
61
src/api/stuwork/activityinfosubsignup.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询活动报名列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfosubsignup/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取活动主题列表
|
||||
*/
|
||||
export const getActivityInfoList = () => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfo/activityInfoList',
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取子项目列表
|
||||
* @param activityInfoId 活动主题ID(可选)
|
||||
*/
|
||||
export const getActivityInfoSubList = (activityInfoId?: string) => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfosub/activityInfoSubList',
|
||||
method: 'get',
|
||||
params: activityInfoId ? { activityInfoId } : {}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除活动报名
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfosubsignup',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导出活动报名表
|
||||
* @param query 查询参数
|
||||
*/
|
||||
export const exportExcel = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/activityinfosubsignup/export',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,13 +1,73 @@
|
||||
import request from "/@/utils/request"
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取考核项目列表
|
||||
* @returns {Promise} 请求的 Promise 对象。
|
||||
* 分页查询考核奖项列表
|
||||
* @param query
|
||||
*/
|
||||
export function getList() {
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentcategory/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取考核奖项列表(不分页)
|
||||
* @param query
|
||||
*/
|
||||
export const getList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentcategory/list',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增考核奖项
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentcategory',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentcategory/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑考核奖项
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentcategory/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除考核奖项
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentcategory/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,13 +1,73 @@
|
||||
import request from "/@/utils/request"
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取考核指标列表
|
||||
* @returns {Promise} 请求的 Promise 对象。
|
||||
* 分页查询考核指标列表
|
||||
* @param query
|
||||
*/
|
||||
export function getList() {
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentpoint/list',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
url: '/stuwork/assessmentpoint/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据考核项ID获取考核指标列表
|
||||
* @param categortyId
|
||||
*/
|
||||
export const getAssessmentPointListByacId = (categortyId: string) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentpoint/getAssessmentPointListByacId',
|
||||
method: 'get',
|
||||
params: { categortyId }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增考核指标
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentpoint',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentpoint/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑考核指标
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentpoint/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除考核指标
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/assessmentpoint/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
62
src/api/stuwork/classactivity.ts
Normal file
62
src/api/stuwork/classactivity.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询活动记录列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classactivity/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增活动记录
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classactivity',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/classactivity/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑活动记录
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classactivity/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除活动记录
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/classactivity/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
75
src/api/stuwork/classfeelog.ts
Normal file
75
src/api/stuwork/classfeelog.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询班费记录列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classfeelog/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增班费记录
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classfeelog',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/classfeelog/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑班费记录
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classfeelog/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除班费记录
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/classfeelog/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导出班费记录
|
||||
* @param query
|
||||
*/
|
||||
export const exportExcel = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classfeelog/export',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,13 +1,84 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询班级荣誉列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classhonor/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增班级荣誉
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classhonor',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/classhonor/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑班级荣誉
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classhonor/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 归档班级荣誉
|
||||
* @param data
|
||||
*/
|
||||
export const editBelong = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classhonor/editBelong',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除班级荣誉
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/classhonor/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据班级代码查询班级荣誉
|
||||
* @param classCode 班级代码
|
||||
*/
|
||||
export const queryClassHonorByClassCode = (classCode: string | number) => {
|
||||
return request({
|
||||
url: `/stuwork/classhonor/queryClassHonorByClassCode/${classCode}`,
|
||||
method: 'get',
|
||||
});
|
||||
return request({
|
||||
url: `/stuwork/classhonor/queryClassHonorByClassCode/${classCode}`,
|
||||
method: 'get',
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
74
src/api/stuwork/classpaper.ts
Normal file
74
src/api/stuwork/classpaper.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询德育论文和案例列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classpaper/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增德育论文和案例
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classpaper',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/classpaper/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑德育论文和案例
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classpaper/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除德育论文和案例
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/classpaper/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 班主任考核加分
|
||||
* @param data
|
||||
*/
|
||||
export const addScore = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classpaper/addScore',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,13 +1,99 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询班级宣传列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classpublicity/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增班级宣传
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classpublicity',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/classpublicity/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑班级宣传
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classpublicity/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 归档班级宣传
|
||||
* @param data
|
||||
*/
|
||||
export const editBelong = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classpublicity/editBelong',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除班级宣传
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/classpublicity/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 加分
|
||||
* @param data
|
||||
*/
|
||||
export const addScore = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classpublicity/edit',
|
||||
method: 'post',
|
||||
data: {
|
||||
...data,
|
||||
isAddScore: '1'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据班级代码查询班级宣传
|
||||
* @param classCode 班级代码
|
||||
*/
|
||||
export const queryDataByClassCode = (classCode: string | number) => {
|
||||
return request({
|
||||
url: `/stuwork/classpublicity/queryDataByClassCode/${classCode}`,
|
||||
method: 'get',
|
||||
});
|
||||
return request({
|
||||
url: `/stuwork/classpublicity/queryDataByClassCode/${classCode}`,
|
||||
method: 'get',
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
75
src/api/stuwork/classsafeedu.ts
Normal file
75
src/api/stuwork/classsafeedu.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询安全教育列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classsafeedu/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增安全教育
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classsafeedu',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/classsafeedu/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑安全教育
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classsafeedu/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除安全教育
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/classsafeedu/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导出安全教育
|
||||
* @param query
|
||||
*/
|
||||
export const exportExcel = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classsafeedu/export',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob' // Important for file downloads
|
||||
});
|
||||
};
|
||||
|
||||
62
src/api/stuwork/classsummary.ts
Normal file
62
src/api/stuwork/classsummary.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询班级总结列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classsummary/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增班级总结
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classsummary',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/classsummary/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑班级总结
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classsummary/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除班级总结
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/classsummary/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
110
src/api/stuwork/classtheme.ts
Normal file
110
src/api/stuwork/classtheme.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询主题班会课教案列表(实际上查询的是上传记录)
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classthemerecord/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/classtheme/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除主题班会课教案
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/classtheme/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化班级主题班会
|
||||
* @param data
|
||||
*/
|
||||
export const initObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classthemerecord',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 分页查询主题班会上传记录
|
||||
* @param query
|
||||
*/
|
||||
export const fetchRecordList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classthemerecord/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增主题班会(上传记录)
|
||||
* @param data
|
||||
*/
|
||||
export const addRecord = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classtheme',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑主题班会(上传记录)
|
||||
* @param data
|
||||
*/
|
||||
export const editRecord = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classtheme/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取主题班会详情
|
||||
* @param id
|
||||
*/
|
||||
export const getRecordDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/classtheme/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除主题班会(上传记录)
|
||||
* @param ids
|
||||
*/
|
||||
export const delRecord = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/classtheme/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
79
src/api/stuwork/rewardclass.ts
Normal file
79
src/api/stuwork/rewardclass.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询文明班级列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardclass/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增文明班级
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardclass',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardclass/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑文明班级
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardclass/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除文明班级
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardclass/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导入文明班级
|
||||
* @param file
|
||||
*/
|
||||
export const importExcel = (file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return request({
|
||||
url: '/stuwork/rewardclass/import',
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
79
src/api/stuwork/rewarddorm.ts
Normal file
79
src/api/stuwork/rewarddorm.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询文明宿舍列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewarddorm/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增文明宿舍
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewarddorm',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/rewarddorm/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑文明宿舍
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewarddorm/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除文明宿舍
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/rewarddorm/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导入文明宿舍
|
||||
* @param file
|
||||
*/
|
||||
export const importExcel = (file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return request({
|
||||
url: '/stuwork/rewarddorm/import',
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
74
src/api/stuwork/rewardrule.ts
Normal file
74
src/api/stuwork/rewardrule.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询评优评先奖项列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardrule/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取评优评先奖项列表(不分页)
|
||||
* @param query
|
||||
*/
|
||||
export const getList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardrule/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增评优评先奖项
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardrule',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardrule/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑评优评先奖项
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardrule/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除评优评先奖项
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardrule/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
27
src/api/stuwork/rewardstudent.ts
Normal file
27
src/api/stuwork/rewardstudent.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取学生评优评先列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardstudent/getList',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导出学生评优评先
|
||||
* @param query
|
||||
*/
|
||||
export const exportExcel = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/rewardstudent/export',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
});
|
||||
};
|
||||
|
||||
61
src/api/stuwork/stipendtermbatch.ts
Normal file
61
src/api/stuwork/stipendtermbatch.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询助学金申请批次列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stipendtermbatch/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增助学金申请批次
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stipendtermbatch',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: `/stuwork/stipendtermbatch/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑助学金申请批次
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stipendtermbatch/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除助学金申请批次
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/stipendtermbatch/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
61
src/api/stuwork/stuassociation.ts
Normal file
61
src/api/stuwork/stuassociation.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询社团列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuassociation/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增社团
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuassociation',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: `/stuwork/stuassociation/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑社团
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuassociation/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除社团
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/stuassociation',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
14
src/api/stuwork/stuassociationmember.ts
Normal file
14
src/api/stuwork/stuassociationmember.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询社团成员列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuassociationmember/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
74
src/api/stuwork/stucare.ts
Normal file
74
src/api/stuwork/stucare.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询心理健康列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stucare/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增心理健康
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stucare',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/stucare/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑心理健康
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stucare/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除心理健康
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/stucare/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新干预结果
|
||||
* @param data
|
||||
*/
|
||||
export const updateResult = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stucare/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
103
src/api/stuwork/stuconduct.ts
Normal file
103
src/api/stuwork/stuconduct.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询操行考核列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuconduct/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增操行考核
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuconduct',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/stuconduct/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑操行考核
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuconduct/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除操行考核
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/stuconduct/delete',
|
||||
method: 'post',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导入操行考核
|
||||
* @param file
|
||||
*/
|
||||
export const importExcel = (file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return request({
|
||||
url: '/stuwork/stuconduct/import',
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 学期操行考核查询
|
||||
* @param query
|
||||
*/
|
||||
export const getStuConductTerm = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuconduct/getStuConductTerm',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 学年操行考核查询
|
||||
* @param query
|
||||
*/
|
||||
export const getStuConductYear = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuconduct/getStuConductYear',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
37
src/api/stuwork/stuunion.ts
Normal file
37
src/api/stuwork/stuunion.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询学生会列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuunion/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: `/stuwork/stuunion/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑学生会
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuunion/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
91
src/api/stuwork/stuunionleague.ts
Normal file
91
src/api/stuwork/stuunionleague.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询团员列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuunionleague/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增团员
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuunionleague',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: `/stuwork/stuunionleague/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑团员
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuunionleague/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除团员
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/stuunionleague',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导入团员
|
||||
* @param file 文件
|
||||
*/
|
||||
export const importExcel = (file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return request({
|
||||
url: '/stuwork/stuunionleague/import',
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导出团员
|
||||
* @param query 查询参数
|
||||
*/
|
||||
export const exportExcel = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/stuunionleague/export',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
});
|
||||
};
|
||||
|
||||
85
src/api/stuwork/tuitionfreestu.ts
Normal file
85
src/api/stuwork/tuitionfreestu.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询免学费申请列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreestu/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 申请免学费
|
||||
* @param data
|
||||
*/
|
||||
export const applyObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreestu/apply',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: `/stuwork/tuitionfreestu/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreestu',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreestu',
|
||||
method: 'put',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param id
|
||||
*/
|
||||
export const delObj = (id: string) => {
|
||||
return request({
|
||||
url: `/stuwork/tuitionfreestu/${id}`,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导出
|
||||
* @param query
|
||||
*/
|
||||
export const exportExcel = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreestu/export',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
});
|
||||
};
|
||||
|
||||
26
src/api/stuwork/tuitionfreestuapply.ts
Normal file
26
src/api/stuwork/tuitionfreestuapply.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询免学费申请学生列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/basic/basicstudent/getTuitionFreeStu',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 申请免学费
|
||||
* @param data
|
||||
*/
|
||||
export const applyObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreestuapply/apply',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
26
src/api/stuwork/tuitionfreestuapprove.ts
Normal file
26
src/api/stuwork/tuitionfreestuapprove.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取待审批数据(按班级)
|
||||
* @param query
|
||||
*/
|
||||
export const getApproveData = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreestu/getApproveData',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取已审批数据(按学院分组,班级数、人数)
|
||||
* @param query
|
||||
*/
|
||||
export const getApprovedData = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreestu/getDataGroupDept',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
62
src/api/stuwork/tuitionfreeterm.ts
Normal file
62
src/api/stuwork/tuitionfreeterm.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询免学费批次列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreeterm/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增免学费批次
|
||||
* @param data
|
||||
*/
|
||||
export const addObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreeterm',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param id
|
||||
*/
|
||||
export const getDetail = (id: string) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreeterm/detail',
|
||||
method: 'get',
|
||||
params: { id }
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 编辑免学费批次
|
||||
* @param data
|
||||
*/
|
||||
export const editObj = (data: any) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreeterm/edit',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除免学费批次
|
||||
* @param ids
|
||||
*/
|
||||
export const delObj = (ids: string[]) => {
|
||||
return request({
|
||||
url: '/stuwork/tuitionfreeterm',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
});
|
||||
};
|
||||
|
||||
1
src/assets/Untitled
Normal file
1
src/assets/Untitled
Normal file
@@ -0,0 +1 @@
|
||||
assessmentcategory
|
||||
BIN
src/assets/file/文明班级导入模板.xlsx
Normal file
BIN
src/assets/file/文明班级导入模板.xlsx
Normal file
Binary file not shown.
178
src/views/ems/qualityReport/edit.vue
Normal file
178
src/views/ems/qualityReport/edit.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="编辑评语"
|
||||
v-model="visible"
|
||||
:width="700"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="学号">
|
||||
<el-input v-model="form.stuNo" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="form.realName" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="学年">
|
||||
<el-input v-model="form.schoolYear" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="学期">
|
||||
<el-input v-model="form.schoolTerm" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="评语" prop="comment">
|
||||
<el-input
|
||||
v-model="form.comment"
|
||||
type="textarea"
|
||||
:rows="6"
|
||||
placeholder="请输入评语"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="家长寄语" prop="parentalMsg">
|
||||
<el-input
|
||||
v-model="form.parentalMsg"
|
||||
type="textarea"
|
||||
:rows="6"
|
||||
placeholder="请输入家长寄语"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="QualityReportEditDialog">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { updatePY } from '/@/api/ems/qualityReport'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const schoolTermList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
stuNo: '',
|
||||
realName: '',
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
comment: '',
|
||||
parentalMsg: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
// comment 和 parentalMsg 非必填,不需要验证规则
|
||||
}
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.stuNo = row.stuNo || ''
|
||||
form.realName = row.realName || ''
|
||||
form.schoolYear = row.schoolYear || ''
|
||||
form.schoolTerm = row.schoolTerm || ''
|
||||
form.comment = row.comment || ''
|
||||
form.parentalMsg = row.parentalMsg || ''
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
stuNo: form.stuNo,
|
||||
comment: form.comment || '',
|
||||
parentalMsg: form.parentalMsg || '',
|
||||
schoolYear: form.schoolYear,
|
||||
schoolTerm: form.schoolTerm
|
||||
}
|
||||
|
||||
await updatePY(submitData)
|
||||
useMessage().success('保存成功')
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '保存失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
getSchoolTermDict()
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
508
src/views/ems/qualityReport/index.vue
Normal file
508
src/views/ems/qualityReport/index.vue
Normal file
@@ -0,0 +1,508 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px"
|
||||
@change="handleDeptChange">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学号" prop="stuNo">
|
||||
<el-input
|
||||
v-model="state.queryForm.stuNo"
|
||||
placeholder="请输入学号"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="state.queryForm.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Upload"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleImportComment">
|
||||
评语导入
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Calendar"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleSetClassStartTime">
|
||||
设置班级开学时间
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleExport">
|
||||
名单导出
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="stuNo" label="学号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="comment" label="评语" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="parentalMsg" label="家长寄语" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 编辑评语弹窗 -->
|
||||
<edit-dialog ref="editDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 评语导入弹窗 -->
|
||||
<el-dialog
|
||||
title="评语导入"
|
||||
v-model="importDialogVisible"
|
||||
:width="500"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:auto-upload="false"
|
||||
:on-change="handleFileChange"
|
||||
:limit="1"
|
||||
accept=".xlsx,.xls"
|
||||
drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
只能上传 xlsx/xls 文件
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="importDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :disabled="!importFile || importLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 设置班级开学时间弹窗 -->
|
||||
<el-dialog
|
||||
title="设置班级开学时间"
|
||||
v-model="startTimeDialogVisible"
|
||||
:width="500"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="startTimeFormRef"
|
||||
:model="startTimeForm"
|
||||
:rules="startTimeRules"
|
||||
label-width="120px"
|
||||
v-loading="startTimeLoading">
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="startTimeForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开学时间" prop="startTime">
|
||||
<el-date-picker
|
||||
v-model="startTimeForm.startTime"
|
||||
type="date"
|
||||
placeholder="选择开学时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="startTimeDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleStartTimeSubmit" :disabled="startTimeLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="QualityReport">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, importComment, setClassStartTime, exportExcel } from "/@/api/ems/qualityReport";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import { UploadFilled } from '@element-plus/icons-vue'
|
||||
import EditDialog from './edit.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const editDialogRef = ref()
|
||||
const uploadRef = ref()
|
||||
const startTimeFormRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const importDialogVisible = ref(false)
|
||||
const importFile = ref<File | null>(null)
|
||||
const importLoading = ref(false)
|
||||
const startTimeDialogVisible = ref(false)
|
||||
const startTimeLoading = ref(false)
|
||||
|
||||
// 设置班级开学时间表单
|
||||
const startTimeForm = reactive({
|
||||
classCode: '',
|
||||
startTime: ''
|
||||
})
|
||||
|
||||
// 设置班级开学时间表单验证规则
|
||||
const startTimeRules = {
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班级', trigger: 'change' }
|
||||
],
|
||||
startTime: [
|
||||
{ required: true, message: '请选择开学时间', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
deptCode: '',
|
||||
stuNo: '',
|
||||
realName: '',
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
classCode: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 学院变化
|
||||
const handleDeptChange = () => {
|
||||
// 可以根据学院筛选班级,这里暂时不实现
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.stuNo = ''
|
||||
state.queryForm.realName = ''
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.classCode = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 评语导入
|
||||
const handleImportComment = () => {
|
||||
importDialogVisible.value = true
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
}
|
||||
|
||||
// 文件变化
|
||||
const handleFileChange = (file: any) => {
|
||||
importFile.value = file.raw
|
||||
}
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (!importFile.value) {
|
||||
useMessage().warning('请选择要导入的文件')
|
||||
return
|
||||
}
|
||||
|
||||
importLoading.value = true
|
||||
try {
|
||||
await importComment(importFile.value)
|
||||
useMessage().success('导入成功')
|
||||
importDialogVisible.value = false
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败')
|
||||
} finally {
|
||||
importLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 设置班级开学时间
|
||||
const handleSetClassStartTime = () => {
|
||||
startTimeDialogVisible.value = true
|
||||
startTimeForm.classCode = ''
|
||||
startTimeForm.startTime = ''
|
||||
startTimeFormRef.value?.resetFields()
|
||||
}
|
||||
|
||||
// 提交设置班级开学时间
|
||||
const handleStartTimeSubmit = async () => {
|
||||
if (!startTimeFormRef.value) return
|
||||
|
||||
await startTimeFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
startTimeLoading.value = true
|
||||
try {
|
||||
await setClassStartTime({
|
||||
classCode: startTimeForm.classCode,
|
||||
startTime: startTimeForm.startTime
|
||||
})
|
||||
useMessage().success('设置成功')
|
||||
startTimeDialogVisible.value = false
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '设置失败')
|
||||
} finally {
|
||||
startTimeLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 名单导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const res = await exportExcel(state.queryForm)
|
||||
|
||||
// 创建blob对象
|
||||
const blob = new Blob([res as unknown as BlobPart], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
})
|
||||
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
|
||||
// 设置文件名
|
||||
const fileName = `素质报告单名单_${new Date().getTime()}.xlsx`
|
||||
link.setAttribute('download', fileName)
|
||||
|
||||
// 触发下载
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
|
||||
// 清理
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
|
||||
useMessage().success('导出成功')
|
||||
} catch (err: any) {
|
||||
console.error('导出失败', err)
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
editDialogRef.value?.openDialog(row)
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
268
src/views/stuwork/activityawards/form.vue
Normal file
268
src/views/stuwork/activityawards/form.vue
Normal file
@@ -0,0 +1,268 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑获奖活动信息' : '新增获奖活动信息'"
|
||||
v-model="visible"
|
||||
:width="700"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="活动主题" prop="activityInfoId">
|
||||
<el-select
|
||||
v-model="form.activityInfoId"
|
||||
placeholder="请选择活动主题"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in activityInfoList"
|
||||
:key="item.id"
|
||||
:label="item.activityTheme"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学号" prop="userName">
|
||||
<el-input
|
||||
v-model="form.userName"
|
||||
placeholder="请输入学号"
|
||||
clearable
|
||||
@blur="handleStuNoBlur"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="form.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="获奖信息" prop="awards">
|
||||
<el-input
|
||||
v-model="form.awards"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入获奖信息"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="获奖时间" prop="awardTime">
|
||||
<el-date-picker
|
||||
v-model="form.awardTime"
|
||||
type="date"
|
||||
placeholder="请选择获奖时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ActivityAwardsFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail, getActivityInfoList } from '/@/api/stuwork/activityawards'
|
||||
import { queryAllStudentByStuNo } from '/@/api/basic/basicstudent'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const activityInfoList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
activityInfoId: '',
|
||||
userName: '',
|
||||
realName: '',
|
||||
awards: '',
|
||||
awardTime: '',
|
||||
remarks: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
activityInfoId: [
|
||||
{ required: true, message: '请选择活动主题', trigger: 'change' }
|
||||
],
|
||||
userName: [
|
||||
{ required: true, message: '请输入学号', trigger: 'blur' }
|
||||
],
|
||||
realName: [
|
||||
{ required: true, message: '请输入姓名', trigger: 'blur' }
|
||||
],
|
||||
awards: [
|
||||
{ required: true, message: '请输入获奖信息', trigger: 'blur' }
|
||||
],
|
||||
awardTime: [
|
||||
{ required: true, message: '请选择获奖时间', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 学号失焦时自动填充姓名
|
||||
const handleStuNoBlur = async () => {
|
||||
if (!form.userName) return
|
||||
|
||||
try {
|
||||
const res = await queryAllStudentByStuNo({ stuNo: form.userName })
|
||||
if (res.data && res.data.length > 0) {
|
||||
const student = res.data[0]
|
||||
form.realName = student.realName || ''
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('查询学生信息失败', err)
|
||||
// 不显示错误,允许手动输入姓名
|
||||
}
|
||||
}
|
||||
|
||||
// 获取活动主题列表
|
||||
const getActivityInfoListData = async () => {
|
||||
try {
|
||||
const res = await getActivityInfoList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
activityInfoList.value = res.data
|
||||
} else {
|
||||
activityInfoList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取活动主题列表失败', err)
|
||||
activityInfoList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
operType.value = type
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.activityInfoId = ''
|
||||
form.userName = ''
|
||||
form.realName = ''
|
||||
form.awards = ''
|
||||
form.awardTime = ''
|
||||
form.remarks = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.activityInfoId = row.activityInfoId || ''
|
||||
form.userName = row.userName || ''
|
||||
form.realName = row.realName || ''
|
||||
form.awards = row.awards || ''
|
||||
form.awardTime = row.awardTime || row.month || ''
|
||||
form.remarks = row.remarks || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.userName || !row.awards)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.activityInfoId = res.data.activityInfoId || ''
|
||||
form.userName = res.data.userName || ''
|
||||
form.realName = res.data.realName || ''
|
||||
form.awards = res.data.awards || ''
|
||||
form.awardTime = res.data.awardTime || res.data.month || ''
|
||||
form.remarks = res.data.remarks || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
activityInfoId: form.activityInfoId,
|
||||
userName: form.userName,
|
||||
realName: form.realName,
|
||||
awards: form.awards,
|
||||
awardTime: form.awardTime,
|
||||
remarks: form.remarks || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'edit' && form.id) {
|
||||
await editObj({ ...submitData, id: form.id })
|
||||
useMessage().success('编辑成功')
|
||||
} else {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
}
|
||||
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'edit' ? '编辑失败' : '新增失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getActivityInfoListData()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
245
src/views/stuwork/activityawards/index.vue
Normal file
245
src/views/stuwork/activityawards/index.vue
Normal file
@@ -0,0 +1,245 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Upload"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleImport">
|
||||
导入
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="activityTheme" label="活动主题" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="userName" label="学号" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="awards" label="获奖信息" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="awardTime" label="获奖时间" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.awardTime || scope.row.month, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remarks" label="备注" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 导入弹窗 -->
|
||||
<el-dialog
|
||||
title="导入获奖活动信息"
|
||||
v-model="importDialogVisible"
|
||||
:width="500"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<div style="margin-bottom: 15px;">
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="success"
|
||||
@click="handleDownloadTemplate">
|
||||
下载模板
|
||||
</el-button>
|
||||
</div>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:auto-upload="false"
|
||||
:on-change="handleFileChange"
|
||||
:limit="1"
|
||||
accept=".xlsx,.xls"
|
||||
drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
只能上传 xlsx/xls 文件
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="importDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :disabled="!importFile || importLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ActivityAwards">
|
||||
import { reactive, ref } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, importExcel } from "/@/api/stuwork/activityawards";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
import { UploadFilled } from '@element-plus/icons-vue'
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const uploadRef = ref()
|
||||
const showSearch = ref(false)
|
||||
const importDialogVisible = ref(false)
|
||||
const importFile = ref<File | null>(null)
|
||||
const importLoading = ref(false)
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该获奖活动信息吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导入
|
||||
const handleImport = () => {
|
||||
importDialogVisible.value = true
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
}
|
||||
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
try {
|
||||
const fileName = '获奖活动信息导入模板.xlsx'
|
||||
// 使用动态导入获取文件URL,从 views/stuwork/activityawards 到 assets/file 的相对路径
|
||||
const fileUrl = new URL(`../../../assets/file/${fileName}`, import.meta.url).href
|
||||
const response = await fetch(fileUrl)
|
||||
if (!response.ok) {
|
||||
throw new Error('文件下载失败')
|
||||
}
|
||||
const blob = await response.blob()
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = fileName
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
window.URL.revokeObjectURL(url)
|
||||
document.body.removeChild(link)
|
||||
useMessage().success('模板下载成功')
|
||||
} catch (error) {
|
||||
console.error('模板下载失败', error)
|
||||
useMessage().error('模板下载失败,请检查模板文件是否存在')
|
||||
}
|
||||
}
|
||||
|
||||
// 文件变化
|
||||
const handleFileChange = (file: any) => {
|
||||
importFile.value = file.raw
|
||||
}
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (!importFile.value) {
|
||||
useMessage().warning('请选择要导入的文件')
|
||||
return
|
||||
}
|
||||
|
||||
importLoading.value = true
|
||||
try {
|
||||
await importExcel(importFile.value)
|
||||
useMessage().success('导入成功')
|
||||
importDialogVisible.value = false
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败')
|
||||
} finally {
|
||||
importLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
76
src/views/stuwork/activityinfo/detail.vue
Normal file
76
src/views/stuwork/activityinfo/detail.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="查看详情"
|
||||
v-model="visible"
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
width="800px">
|
||||
<div v-loading="loading" class="detail-container" v-if="detailData">
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="活动主题" :span="2">
|
||||
{{ detailData.activityTheme || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="活动说明" :span="2">
|
||||
{{ detailData.remarks || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="活动兼报数">
|
||||
{{ detailData.maxSub !== undefined && detailData.maxSub !== null ? detailData.maxSub : '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="开始时间">
|
||||
{{ parseTime(detailData.startTime, '{y}-{m}-{d}') }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="结束时间">
|
||||
{{ parseTime(detailData.endTime, '{y}-{m}-{d}') }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ActivityInfoDetailDialog">
|
||||
import { ref } from 'vue'
|
||||
import { getDetail } from '/@/api/stuwork/activityinfo'
|
||||
import { parseTime } from '/@/utils/formatTime'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
|
||||
// 定义变量内容
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const detailData = ref<any>({})
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (id: string) => {
|
||||
visible.value = true
|
||||
loading.value = true
|
||||
detailData.value = {}
|
||||
|
||||
try {
|
||||
const res = await getDetail(id)
|
||||
if (res.data) {
|
||||
detailData.value = res.data
|
||||
}
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '获取详情失败')
|
||||
visible.value = false
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.detail-container {
|
||||
padding: 20px 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
167
src/views/stuwork/activityinfo/form.vue
Normal file
167
src/views/stuwork/activityinfo/form.vue
Normal file
@@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑活动' : '新增活动'"
|
||||
v-model="visible"
|
||||
:width="700"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="活动主题" prop="activityTheme">
|
||||
<el-input
|
||||
v-model="form.activityTheme"
|
||||
placeholder="请输入活动主题"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="活动说明" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入活动说明"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="活动兼报数" prop="maxSub">
|
||||
<el-input-number
|
||||
v-model="form.maxSub"
|
||||
:min="0"
|
||||
:max="100"
|
||||
placeholder="请输入活动兼报数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ActivityInfoFormDialog">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/activityinfo'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
activityTheme: '',
|
||||
remarks: '',
|
||||
maxSub: undefined as number | undefined
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
activityTheme: [
|
||||
{ required: true, message: '请输入活动主题', trigger: 'blur' }
|
||||
],
|
||||
remarks: [
|
||||
{ required: true, message: '请输入活动说明', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
operType.value = type
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.activityTheme = ''
|
||||
form.remarks = ''
|
||||
form.maxSub = undefined
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.activityTheme = row.activityTheme || ''
|
||||
form.remarks = row.remarks || ''
|
||||
form.maxSub = row.maxSub !== undefined && row.maxSub !== null ? row.maxSub : undefined
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.activityTheme || !row.remarks)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.activityTheme = res.data.activityTheme || ''
|
||||
form.remarks = res.data.remarks || ''
|
||||
form.maxSub = res.data.maxSub !== undefined && res.data.maxSub !== null ? res.data.maxSub : undefined
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
activityTheme: form.activityTheme,
|
||||
remarks: form.remarks,
|
||||
maxSub: form.maxSub !== undefined && form.maxSub !== null ? form.maxSub : undefined
|
||||
}
|
||||
|
||||
if (operType.value === 'edit' && form.id) {
|
||||
await editObj({ ...submitData, id: form.id })
|
||||
useMessage().success('编辑成功')
|
||||
} else {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
}
|
||||
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'edit' ? '编辑失败' : '新增失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
244
src/views/stuwork/activityinfo/index.vue
Normal file
244
src/views/stuwork/activityinfo/index.vue
Normal file
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="activityTheme" label="活动主题" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="remarks" label="活动说明" show-overflow-tooltip align="center" min-width="300" />
|
||||
<el-table-column prop="maxSub" label="活动兼报数" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.maxSub || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="startTime" label="开始时间" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="endTime" label="结束时间" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="300" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleView(scope.row)">
|
||||
查看详情
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Upload"
|
||||
text
|
||||
type="success"
|
||||
@click="handleImportSub(scope.row)">
|
||||
导入子项目
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 查看详情弹窗 -->
|
||||
<detail-dialog ref="detailDialogRef" />
|
||||
|
||||
<!-- 导入子项目弹窗 -->
|
||||
<el-dialog
|
||||
title="导入子项目"
|
||||
v-model="importDialogVisible"
|
||||
:width="500"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<div style="margin-bottom: 15px;">
|
||||
<el-text>活动主题:{{ currentActivity?.activityTheme || '-' }}</el-text>
|
||||
</div>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:auto-upload="false"
|
||||
:on-change="handleFileChange"
|
||||
:limit="1"
|
||||
accept=".xlsx,.xls"
|
||||
drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
只能上传 xlsx/xls 文件
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="importDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :disabled="!importFile || importLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ActivityInfo">
|
||||
import { reactive, ref } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, importSub } from "/@/api/stuwork/activityinfo";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
import { UploadFilled } from '@element-plus/icons-vue'
|
||||
import FormDialog from './form.vue'
|
||||
import DetailDialog from './detail.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const detailDialogRef = ref()
|
||||
const uploadRef = ref()
|
||||
const showSearch = ref(false)
|
||||
const importDialogVisible = ref(false)
|
||||
const importFile = ref<File | null>(null)
|
||||
const importLoading = ref(false)
|
||||
const currentActivity = ref<any>(null)
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 查看详情
|
||||
const handleView = (row: any) => {
|
||||
detailDialogRef.value?.openDialog(row.id)
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该活动吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导入子项目
|
||||
const handleImportSub = (row: any) => {
|
||||
currentActivity.value = row
|
||||
importFile.value = null
|
||||
importDialogVisible.value = true
|
||||
uploadRef.value?.clearFiles()
|
||||
}
|
||||
|
||||
// 文件变化
|
||||
const handleFileChange = (file: any) => {
|
||||
importFile.value = file.raw
|
||||
}
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (!importFile.value) {
|
||||
useMessage().warning('请选择要上传的文件!')
|
||||
return
|
||||
}
|
||||
|
||||
if (!currentActivity.value?.id) {
|
||||
useMessage().warning('活动信息不存在!')
|
||||
return
|
||||
}
|
||||
|
||||
importLoading.value = true
|
||||
try {
|
||||
await importSub(currentActivity.value.id, importFile.value)
|
||||
useMessage().success('导入成功')
|
||||
importDialogVisible.value = false
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败')
|
||||
} finally {
|
||||
importLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
174
src/views/stuwork/activityinfosub/index.vue
Normal file
174
src/views/stuwork/activityinfosub/index.vue
Normal file
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="活动主题" prop="activityInfoId">
|
||||
<el-select
|
||||
v-model="state.queryForm.activityInfoId"
|
||||
placeholder="请选择活动主题"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 300px">
|
||||
<el-option
|
||||
v-for="item in activityInfoList"
|
||||
:key="item.id"
|
||||
:label="item.activityTheme"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="activityTheme" label="活动主题" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="subTitle" label="子项目名称" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="projectDescription" label="项目描述" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="startTime" label="开始时间" show-overflow-tooltip align="center" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="endTime" label="结束时间" show-overflow-tooltip align="center" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="maxNum" label="报名人数限制" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.maxNum !== undefined && scope.row.maxNum !== null ? scope.row.maxNum : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remarks" label="活动说明" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ActivityInfoSub">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, getActivityInfoList } from "/@/api/stuwork/activityinfosub";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const activityInfoList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
activityInfoId: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.activityInfoId = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该活动子项目吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取活动主题列表
|
||||
const getActivityInfoListData = async () => {
|
||||
try {
|
||||
const res = await getActivityInfoList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
activityInfoList.value = res.data
|
||||
} else {
|
||||
activityInfoList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取活动主题列表失败', err)
|
||||
activityInfoList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getActivityInfoListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
260
src/views/stuwork/activityinfosubsignup/index.vue
Normal file
260
src/views/stuwork/activityinfosubsignup/index.vue
Normal file
@@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="活动主题" prop="activityInfoId">
|
||||
<el-select
|
||||
v-model="state.queryForm.activityInfoId"
|
||||
placeholder="请选择活动主题"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 300px"
|
||||
@change="handleActivityChange">
|
||||
<el-option
|
||||
v-for="item in activityInfoList"
|
||||
:key="item.id"
|
||||
:label="item.activityTheme"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="子项目" prop="activityInfoSubId">
|
||||
<el-select
|
||||
v-model="state.queryForm.activityInfoSubId"
|
||||
placeholder="请选择子项目"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 300px">
|
||||
<el-option
|
||||
v-for="item in filteredSubList"
|
||||
:key="item.id"
|
||||
:label="item.subTitle"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学号/工号" prop="userName">
|
||||
<el-input
|
||||
v-model="state.queryForm.userName"
|
||||
placeholder="请输入学号/工号"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleExport"
|
||||
:loading="exportLoading">
|
||||
导出
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="activityTheme" label="活动主题" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="subTitle" label="子项目" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="remarks" label="项目描述" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="userName" label="学号/工号" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="deptName" label="学院名称" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="classNo" label="班号" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="classMasterName" label="班主任" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="phone" label="联系电话" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ActivityInfoSubSignup">
|
||||
import { reactive, ref, onMounted, computed } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, exportExcel, getActivityInfoList, getActivityInfoSubList } from "/@/api/stuwork/activityinfosubsignup";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const exportLoading = ref(false)
|
||||
const activityInfoList = ref<any[]>([])
|
||||
const subList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
activityInfoId: '',
|
||||
activityInfoSubId: '',
|
||||
userName: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 根据活动主题过滤子项目列表
|
||||
const filteredSubList = computed(() => {
|
||||
if (!state.queryForm.activityInfoId) {
|
||||
return subList.value
|
||||
}
|
||||
return subList.value.filter((item: any) => item.activityInfoId === state.queryForm.activityInfoId)
|
||||
})
|
||||
|
||||
// 活动主题变化时,清空子项目选择并重新加载子项目列表
|
||||
const handleActivityChange = async () => {
|
||||
state.queryForm.activityInfoSubId = ''
|
||||
if (state.queryForm.activityInfoId) {
|
||||
await getSubListData(state.queryForm.activityInfoId)
|
||||
} else {
|
||||
await getSubListData()
|
||||
}
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.activityInfoId = ''
|
||||
state.queryForm.activityInfoSubId = ''
|
||||
state.queryForm.userName = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该活动报名记录吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
exportLoading.value = true
|
||||
try {
|
||||
const res = await exportExcel(state.queryForm)
|
||||
// 创建 Blob 对象
|
||||
const blob = new Blob([res.data as BlobPart], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
})
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = `活动报名表_${new Date().getTime()}.xlsx`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
window.URL.revokeObjectURL(url)
|
||||
document.body.removeChild(link)
|
||||
useMessage().success('导出成功')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取活动主题列表
|
||||
const getActivityInfoListData = async () => {
|
||||
try {
|
||||
const res = await getActivityInfoList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
activityInfoList.value = res.data
|
||||
} else {
|
||||
activityInfoList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取活动主题列表失败', err)
|
||||
activityInfoList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取子项目列表
|
||||
const getSubListData = async (activityInfoId?: string) => {
|
||||
try {
|
||||
const res = await getActivityInfoSubList(activityInfoId)
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
subList.value = res.data
|
||||
} else {
|
||||
subList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取子项目列表失败', err)
|
||||
subList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getActivityInfoListData()
|
||||
getSubListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
165
src/views/stuwork/assessmentcategory/form.vue
Normal file
165
src/views/stuwork/assessmentcategory/form.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑考核奖项' : '新增考核奖项'"
|
||||
v-model="visible"
|
||||
:width="600"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="100px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="考核项名称" prop="category">
|
||||
<el-input
|
||||
v-model="form.category"
|
||||
placeholder="请输入考核项名称"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="考核类型" prop="type">
|
||||
<el-select
|
||||
v-model="form.type"
|
||||
placeholder="请选择考核类型"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="AssessmentCategoryFormDialog">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/assessmentcategory'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
|
||||
// 考核类型列表
|
||||
const typeList = ref([
|
||||
{ label: '常规考核', value: '0' },
|
||||
{ label: '顶岗考核', value: '1' }
|
||||
])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
category: '',
|
||||
type: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
category: [
|
||||
{ required: true, message: '请输入考核项名称', trigger: 'blur' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择考核类型', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.category = ''
|
||||
form.type = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.category = row.category || ''
|
||||
form.type = row.type || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.category || !row.type)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.category = res.data.category || ''
|
||||
form.type = res.data.type || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
category: form.category,
|
||||
type: form.type
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
178
src/views/stuwork/assessmentcategory/index.vue
Normal file
178
src/views/stuwork/assessmentcategory/index.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="考核类型" prop="type">
|
||||
<el-select
|
||||
v-model="state.queryForm.type"
|
||||
placeholder="请选择考核类型"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="category" label="考核项名称" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="type" label="考核类型" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatType(scope.row.type) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remarks" label="备注" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="AssessmentCategory">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/assessmentcategory";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
|
||||
// 考核类型列表
|
||||
const typeList = ref([
|
||||
{ label: '常规考核', value: '0' },
|
||||
{ label: '顶岗考核', value: '1' }
|
||||
])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
type: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化考核类型
|
||||
const formatType = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = typeList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.type = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该考核奖项吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
214
src/views/stuwork/assessmentpoint/form.vue
Normal file
214
src/views/stuwork/assessmentpoint/form.vue
Normal file
@@ -0,0 +1,214 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑考核指标' : '新增考核指标'"
|
||||
v-model="visible"
|
||||
:width="700"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="考核项" prop="categortyId">
|
||||
<el-select
|
||||
v-model="form.categortyId"
|
||||
placeholder="请选择考核项"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in categoryList"
|
||||
:key="item.id"
|
||||
:label="item.category"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="指标名称" prop="pointName">
|
||||
<el-input
|
||||
v-model="form.pointName"
|
||||
placeholder="请输入指标名称"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="评分标准" prop="standard">
|
||||
<el-input
|
||||
v-model="form.standard"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入评分标准"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入备注"
|
||||
:maxlength="250"
|
||||
show-word-limit
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="AssessmentPointFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/assessmentpoint'
|
||||
import { getList } from '/@/api/stuwork/assessmentcategory'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const categoryList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
categortyId: '',
|
||||
pointName: '',
|
||||
standard: '',
|
||||
remarks: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
categortyId: [
|
||||
{ required: true, message: '请选择考核项', trigger: 'change' }
|
||||
],
|
||||
pointName: [
|
||||
{ required: true, message: '请输入指标名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.categortyId = ''
|
||||
form.pointName = ''
|
||||
form.standard = ''
|
||||
form.remarks = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.categortyId = row.categortyId || ''
|
||||
form.pointName = row.pointName || ''
|
||||
form.standard = row.standard || ''
|
||||
form.remarks = row.remarks || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.pointName || !row.standard)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.categortyId = res.data.categortyId || ''
|
||||
form.pointName = res.data.pointName || ''
|
||||
form.standard = res.data.standard || ''
|
||||
form.remarks = res.data.remarks || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
categortyId: form.categortyId,
|
||||
pointName: form.pointName,
|
||||
standard: form.standard || '',
|
||||
remarks: form.remarks || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取考核项列表
|
||||
const getCategoryList = async () => {
|
||||
try {
|
||||
const res = await getList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
categoryList.value = res.data
|
||||
} else {
|
||||
categoryList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取考核项列表失败', err)
|
||||
categoryList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getCategoryList()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
159
src/views/stuwork/assessmentpoint/index.vue
Normal file
159
src/views/stuwork/assessmentpoint/index.vue
Normal file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="指标名称" prop="pointName">
|
||||
<el-input
|
||||
v-model="state.queryForm.pointName"
|
||||
placeholder="请输入指标名称"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="categoryName" label="考核项" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="pointName" label="指标名称" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="standard" label="评分标准" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="score" label="默认扣分值" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="remarks" label="备注" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="AssessmentPoint">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/assessmentpoint";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
pointName: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.pointName = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该考核指标吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
// 初始化完成
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
335
src/views/stuwork/classactivity/form.vue
Normal file
335
src/views/stuwork/classactivity/form.vue
Normal file
@@ -0,0 +1,335 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="900"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="form.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="活动主题" prop="themeName">
|
||||
<el-input
|
||||
v-model="form.themeName"
|
||||
placeholder="请输入活动主题"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="主持人" prop="author">
|
||||
<el-input
|
||||
v-model="form.author"
|
||||
placeholder="请输入主持人"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="活动时间" prop="recordDate">
|
||||
<el-date-picker
|
||||
v-model="form.recordDate"
|
||||
type="date"
|
||||
placeholder="选择活动时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="活动地点" prop="address">
|
||||
<el-input
|
||||
v-model="form.address"
|
||||
placeholder="请输入活动地点"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="参加人数" prop="attendNum">
|
||||
<el-input-number
|
||||
v-model="form.attendNum"
|
||||
:min="0"
|
||||
placeholder="请输入参加人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="活动内容" prop="content">
|
||||
<Editor
|
||||
v-model:getHtml="form.content"
|
||||
:height="300"
|
||||
placeholder="请输入活动内容" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="活动图片" prop="attachment">
|
||||
<upload-file
|
||||
v-model="form.attachment"
|
||||
:limit="5"
|
||||
:fileSize="10"
|
||||
type="simple" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="活动图片2" prop="attachment2">
|
||||
<upload-file
|
||||
v-model="form.attachment2"
|
||||
:limit="5"
|
||||
:fileSize="10"
|
||||
type="simple" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassActivityFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/classactivity'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
import { CURRENT_SCHOOL_YEAR, CURRENT_SCHOOL_TERM } from '/@/config/global'
|
||||
import Editor from '/@/components/Editor/index.vue'
|
||||
import UploadFile from '/@/components/Upload/index.vue'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const classList = ref<any[]>([])
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const currentSchoolYear = ref('')
|
||||
const currentSchoolTerm = ref('')
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
classCode: '',
|
||||
themeName: '',
|
||||
author: '',
|
||||
recordDate: '',
|
||||
address: '',
|
||||
attendNum: 0,
|
||||
content: '',
|
||||
attachment: '',
|
||||
attachment2: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班号', trigger: 'change' }
|
||||
],
|
||||
themeName: [
|
||||
{ required: true, message: '请输入活动主题', trigger: 'blur' }
|
||||
],
|
||||
author: [
|
||||
{ required: true, message: '请输入主持人', trigger: 'blur' }
|
||||
],
|
||||
address: [
|
||||
{ required: true, message: '请输入活动地点', trigger: 'blur' }
|
||||
],
|
||||
attendNum: [
|
||||
{ required: true, message: '请输入参加人数', trigger: 'blur' }
|
||||
]
|
||||
// activityTime 和 content 非必填,不需要验证规则
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.classCode = ''
|
||||
form.themeName = ''
|
||||
form.author = ''
|
||||
form.recordDate = ''
|
||||
form.address = ''
|
||||
form.attendNum = 0
|
||||
form.content = ''
|
||||
form.attachment = ''
|
||||
form.attachment2 = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.classCode = row.classCode || ''
|
||||
form.themeName = row.themeName || ''
|
||||
form.author = row.author || ''
|
||||
form.recordDate = row.activityTime || row.recordDate || ''
|
||||
form.address = row.address || ''
|
||||
form.attendNum = row.attendNum || 0
|
||||
form.content = row.content || ''
|
||||
form.attachment = row.attachment || ''
|
||||
form.attachment2 = row.attachment2 || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && !row.content) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.content = res.data.content || ''
|
||||
form.attachment = res.data.attachment || ''
|
||||
form.attachment2 = res.data.attachment2 || ''
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
classCode: form.classCode,
|
||||
schoolYear: currentSchoolYear.value || CURRENT_SCHOOL_YEAR, // 使用当前学年
|
||||
schoolTerm: currentSchoolTerm.value || CURRENT_SCHOOL_TERM, // 使用当前学期
|
||||
themeName: form.themeName,
|
||||
author: form.author,
|
||||
recordDate: form.recordDate || '',
|
||||
address: form.address,
|
||||
attendNum: String(form.attendNum || 0), // API文档示例中是字符串类型
|
||||
content: form.content || '',
|
||||
attachment: form.attachment || '',
|
||||
attachment2: form.attachment2 || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表并设置当前学年
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
// 设置当前学年(如果列表中有的话)
|
||||
const currentYear = schoolYearList.value.find((item: any) => item.year === CURRENT_SCHOOL_YEAR)
|
||||
currentSchoolYear.value = currentYear ? currentYear.year : (schoolYearList.value.length > 0 ? schoolYearList.value[0].year : CURRENT_SCHOOL_YEAR)
|
||||
} else {
|
||||
currentSchoolYear.value = CURRENT_SCHOOL_YEAR
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
currentSchoolYear.value = CURRENT_SCHOOL_YEAR
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典并设置当前学期
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
// 设置当前学期
|
||||
const currentTerm = schoolTermList.value.find((item: any) => item.value === CURRENT_SCHOOL_TERM)
|
||||
currentSchoolTerm.value = currentTerm ? currentTerm.value : (schoolTermList.value.length > 0 ? schoolTermList.value[0].value : CURRENT_SCHOOL_TERM)
|
||||
} else {
|
||||
currentSchoolTerm.value = CURRENT_SCHOOL_TERM
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
currentSchoolTerm.value = CURRENT_SCHOOL_TERM
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getClassListData()
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
316
src/views/stuwork/classactivity/index.vue
Normal file
316
src/views/stuwork/classactivity/index.vue
Normal file
@@ -0,0 +1,316 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="classNo" label="班号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="themeName" label="活动主题" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="author" label="主持人" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="activityTime" label="活动时间" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.activityTime || scope.row.recordDate || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="address" label="活动地点" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="attendNum" label="参加人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="attachment" label="活动图片" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.attachment"
|
||||
icon="Picture"
|
||||
text
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleViewImage(scope.row.attachment)">
|
||||
查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="attachment2" label="活动图片2" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.attachment2"
|
||||
icon="Picture"
|
||||
text
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleViewImage(scope.row.attachment2)">
|
||||
查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassActivity">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/classactivity";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
classCode: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.classCode = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 查看图片
|
||||
const handleViewImage = (url: string) => {
|
||||
if (url) {
|
||||
const urls = typeof url === 'string' ? url.split(',') : [url]
|
||||
urls.forEach((imgUrl: string) => {
|
||||
if (imgUrl.trim()) {
|
||||
window.open(imgUrl.trim(), '_blank')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该活动记录吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getClassListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
368
src/views/stuwork/classfeelog/form.vue
Normal file
368
src/views/stuwork/classfeelog/form.vue
Normal file
@@ -0,0 +1,368 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="form.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
:disabled="!!form.id">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="form.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
:disabled="!!form.id">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="form.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="发生时间" prop="operatTime">
|
||||
<el-date-picker
|
||||
v-model="form.operatTime"
|
||||
type="date"
|
||||
placeholder="选择发生时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select
|
||||
v-model="form.type"
|
||||
placeholder="请选择类型"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="金额" prop="money">
|
||||
<el-input-number
|
||||
v-model="form.money"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入金额"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="经办人" prop="operator">
|
||||
<el-input
|
||||
v-model="form.operator"
|
||||
placeholder="请输入经办人"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="用途" prop="purpose">
|
||||
<el-input
|
||||
v-model="form.purpose"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入用途"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="附件" prop="attachment">
|
||||
<upload-file
|
||||
v-model="form.attachment"
|
||||
:limit="5"
|
||||
:fileSize="10"
|
||||
type="simple" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassFeeLogFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/classfeelog'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
import UploadFile from '/@/components/Upload/index.vue'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const classList = ref<any[]>([])
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
classCode: '',
|
||||
operatTime: '',
|
||||
type: '',
|
||||
money: 0,
|
||||
operator: '',
|
||||
purpose: '',
|
||||
attachment: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
schoolYear: [
|
||||
{ required: true, message: '请选择学年', trigger: 'change' }
|
||||
],
|
||||
schoolTerm: [
|
||||
{ required: true, message: '请选择学期', trigger: 'change' }
|
||||
],
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班级', trigger: 'change' }
|
||||
],
|
||||
operatTime: [
|
||||
{ required: true, message: '请选择发生时间', trigger: 'change' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择类型', trigger: 'change' }
|
||||
],
|
||||
money: [
|
||||
{ required: true, message: '请输入金额', trigger: 'blur' }
|
||||
],
|
||||
operator: [
|
||||
{ required: true, message: '请输入经办人', trigger: 'blur' }
|
||||
],
|
||||
purpose: [
|
||||
{ required: true, message: '请输入用途', trigger: 'blur' }
|
||||
]
|
||||
// attachment 非必填,不需要验证规则
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.schoolYear = ''
|
||||
form.schoolTerm = ''
|
||||
form.classCode = ''
|
||||
form.operatTime = ''
|
||||
form.type = ''
|
||||
form.money = 0
|
||||
form.operator = ''
|
||||
form.purpose = ''
|
||||
form.attachment = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.schoolYear = row.schoolYear || ''
|
||||
form.schoolTerm = row.schoolTerm || ''
|
||||
form.classCode = row.classCode || ''
|
||||
form.operatTime = row.operatTime || ''
|
||||
form.type = row.type || ''
|
||||
form.money = row.money || 0
|
||||
form.operator = row.operator || ''
|
||||
form.purpose = row.purpose || ''
|
||||
form.attachment = row.attachment || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.purpose || !row.attachment)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.attachment = res.data.attachment || ''
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
schoolYear: form.schoolYear,
|
||||
schoolTerm: form.schoolTerm,
|
||||
classCode: form.classCode,
|
||||
operatTime: form.operatTime,
|
||||
type: form.type,
|
||||
money: form.money,
|
||||
operator: form.operator,
|
||||
purpose: form.purpose,
|
||||
attachment: form.attachment || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类型字典
|
||||
const getTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('class_fee_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
typeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类型字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getClassListData()
|
||||
getTypeDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
430
src/views/stuwork/classfeelog/index.vue
Normal file
430
src/views/stuwork/classfeelog/index.vue
Normal file
@@ -0,0 +1,430 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px"
|
||||
@change="handleDeptChange">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select
|
||||
v-model="state.queryForm.type"
|
||||
placeholder="请选择类型"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleExport">
|
||||
导出
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="classNo" label="班级" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="operatTime" label="发生时间" show-overflow-tooltip align="center" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.operatTime || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" label="类型" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatType(scope.row.type) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="money" label="金额" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.money !== null && scope.row.money !== undefined ? scope.row.money.toFixed(2) : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="operator" label="经办人" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="purpose" label="用途" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="attachment" label="附件" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.attachment"
|
||||
icon="Document"
|
||||
text
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleViewAttachment(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassFeeLog">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, exportExcel } from "/@/api/stuwork/classfeelog";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([])
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
deptCode: '',
|
||||
classCode: '',
|
||||
type: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化类型
|
||||
const formatType = (value: string) => {
|
||||
if (!value) return '-'
|
||||
const item = typeList.value.find((item: any) => item.value === value)
|
||||
return item ? item.label : value
|
||||
}
|
||||
|
||||
// 学院变化
|
||||
const handleDeptChange = () => {
|
||||
// 可以根据学院筛选班级,这里暂时不实现
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.classCode = ''
|
||||
state.queryForm.type = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 查看附件
|
||||
const handleViewAttachment = (row: any) => {
|
||||
if (row.attachment) {
|
||||
const urls = typeof row.attachment === 'string' ? row.attachment.split(',') : [row.attachment]
|
||||
urls.forEach((url: string) => {
|
||||
if (url.trim()) {
|
||||
window.open(url.trim(), '_blank')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const res = await exportExcel(state.queryForm)
|
||||
|
||||
// 创建blob对象
|
||||
const blob = new Blob([res], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
})
|
||||
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
|
||||
// 设置文件名
|
||||
const fileName = `班费记录_${new Date().getTime()}.xlsx`
|
||||
link.setAttribute('download', fileName)
|
||||
|
||||
// 触发下载
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
|
||||
// 清理
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
|
||||
useMessage().success('导出成功')
|
||||
} catch (err: any) {
|
||||
console.error('导出失败', err)
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该班费记录吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类型字典
|
||||
const getTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('class_fee_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
typeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
typeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类型字典失败', err)
|
||||
typeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
getTypeDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
179
src/views/stuwork/classhonor/belong.vue
Normal file
179
src/views/stuwork/classhonor/belong.vue
Normal file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="归档"
|
||||
v-model="visible"
|
||||
:width="500"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="标题">
|
||||
<el-input v-model="form.title" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="作者">
|
||||
<el-input v-model="form.author" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="班号">
|
||||
<el-input v-model="form.classNo" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="归档级别" prop="belong">
|
||||
<el-select
|
||||
v-model="form.belong"
|
||||
placeholder="请选择归档级别"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in belongList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassHonorBelongDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { editBelong, getDetail } from '/@/api/stuwork/classhonor'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const belongList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
title: '',
|
||||
author: '',
|
||||
classNo: '',
|
||||
belong: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
belong: [
|
||||
{ required: true, message: '请选择归档级别', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.title = ''
|
||||
form.author = ''
|
||||
form.classNo = ''
|
||||
form.belong = ''
|
||||
|
||||
if (row) {
|
||||
form.id = row.id
|
||||
form.title = row.title || ''
|
||||
form.author = row.author || ''
|
||||
form.classNo = row.classNo || ''
|
||||
form.belong = row.belong || ''
|
||||
|
||||
// 如果没有归档级别,尝试获取详情
|
||||
if (row.id && !row.belong) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.belong = res.data.belong || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
await editBelong({
|
||||
id: form.id,
|
||||
belong: form.belong
|
||||
})
|
||||
useMessage().success('归档成功')
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '归档失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取归档级别字典
|
||||
const getBelongDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('honor_belong_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
belongList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取归档级别字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getBelongDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
209
src/views/stuwork/classhonor/form.vue
Normal file
209
src/views/stuwork/classhonor/form.vue
Normal file
@@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="form.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="作者" prop="author">
|
||||
<el-input
|
||||
v-model="form.author"
|
||||
placeholder="请输入作者"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input
|
||||
v-model="form.title"
|
||||
placeholder="请输入标题"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="附件" prop="attachment">
|
||||
<upload-file
|
||||
v-model="form.attachment"
|
||||
:limit="5"
|
||||
:fileSize="10"
|
||||
type="simple" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassHonorFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/classhonor'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import UploadFile from '/@/components/Upload/index.vue'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
classCode: '',
|
||||
author: '',
|
||||
title: '',
|
||||
attachment: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班号', trigger: 'change' }
|
||||
],
|
||||
author: [
|
||||
{ required: true, message: '请输入作者', trigger: 'blur' }
|
||||
],
|
||||
title: [
|
||||
{ required: true, message: '请输入标题', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.classCode = ''
|
||||
form.author = ''
|
||||
form.title = ''
|
||||
form.attachment = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.classCode = row.classCode || ''
|
||||
form.author = row.author || ''
|
||||
form.title = row.title || ''
|
||||
form.attachment = row.attachment || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.title || !row.attachment)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.attachment = res.data.attachment || ''
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
classCode: form.classCode,
|
||||
author: form.author,
|
||||
title: form.title,
|
||||
attachment: form.attachment || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取班号列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班号列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getClassListData()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
386
src/views/stuwork/classhonor/index.vue
Normal file
386
src/views/stuwork/classhonor/index.vue
Normal file
@@ -0,0 +1,386 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px"
|
||||
@change="handleDeptChange">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="classNo" label="班号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="title" label="标题" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="author" label="作者" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="updateTime" label="更新时间" show-overflow-tooltip align="center" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="belong" label="归档级别" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatBelong(scope.row.belong) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="attachment" label="附件" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.attachment"
|
||||
icon="Document"
|
||||
text
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleViewAttachment(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Folder"
|
||||
text
|
||||
type="warning"
|
||||
@click="handleBelong(scope.row)">
|
||||
归档
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 归档弹窗 -->
|
||||
<belong-dialog ref="belongDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassHonor">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/classhonor";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
import FormDialog from './form.vue'
|
||||
import BelongDialog from './belong.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const belongDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const belongList = ref<any[]>([])
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
deptCode: '',
|
||||
classCode: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化归档级别
|
||||
const formatBelong = (value: string) => {
|
||||
if (!value) return '-'
|
||||
const item = belongList.value.find((item: any) => item.value === value)
|
||||
return item ? item.label : value
|
||||
}
|
||||
|
||||
// 学院变化
|
||||
const handleDeptChange = () => {
|
||||
// 可以根据学院筛选班级,这里暂时不实现
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.classCode = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 查看附件
|
||||
const handleViewAttachment = (row: any) => {
|
||||
if (row.attachment) {
|
||||
const urls = typeof row.attachment === 'string' ? row.attachment.split(',') : [row.attachment]
|
||||
urls.forEach((url: string) => {
|
||||
if (url.trim()) {
|
||||
window.open(url.trim(), '_blank')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 归档
|
||||
const handleBelong = (row: any) => {
|
||||
belongDialogRef.value?.openDialog(row)
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该班级荣誉吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班号列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班号列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取归档级别字典
|
||||
const getBelongDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('honor_belong_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
belongList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
belongList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取归档级别字典失败', err)
|
||||
belongList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
getBelongDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
276
src/views/stuwork/classpaper/detail.vue
Normal file
276
src/views/stuwork/classpaper/detail.vue
Normal file
@@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="查看详情"
|
||||
v-model="visible"
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
width="1000px">
|
||||
<div v-loading="loading" class="article-container" v-if="detailData">
|
||||
<!-- 报纸文章样式 -->
|
||||
<div class="article-header">
|
||||
<h1 class="article-title">{{ detailData.title || '-' }}</h1>
|
||||
<div class="article-meta">
|
||||
<div class="meta-left">
|
||||
<span class="meta-item">类型:{{ formatType(detailData.type) }}</span>
|
||||
<span class="meta-item">发表刊物:{{ detailData.journal || '-' }}</span>
|
||||
<span class="meta-item">发表页码:{{ detailData.page || '-' }}</span>
|
||||
</div>
|
||||
<div class="meta-right">
|
||||
<span class="meta-item">班号:{{ detailData.classNo || '-' }}</span>
|
||||
<span class="meta-item">班主任:{{ detailData.teacherRealName || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="article-content" v-html="detailData.description || '-'"></div>
|
||||
|
||||
<!-- 附件区域 -->
|
||||
<div v-if="attachmentList.length > 0" class="article-attachment">
|
||||
<h3 class="attachment-title">附件</h3>
|
||||
<div class="attachment-list">
|
||||
<div
|
||||
v-for="(url, index) in attachmentList"
|
||||
:key="index"
|
||||
class="attachment-item">
|
||||
<el-icon class="attachment-icon"><Document /></el-icon>
|
||||
<span class="attachment-name">{{ getFileName(url) }}</span>
|
||||
<el-button
|
||||
icon="Download"
|
||||
text
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleDownload(url)">
|
||||
下载
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassPaperDetailDialog">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { getDetail } from '/@/api/stuwork/classpaper'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
import { Document, Download } from '@element-plus/icons-vue'
|
||||
import other from '/@/utils/other'
|
||||
|
||||
// 定义变量内容
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const detailData = ref<any>(null)
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([
|
||||
{ label: '德育论文', value: '0' },
|
||||
{ label: '教案', value: '1' }
|
||||
])
|
||||
|
||||
// 附件列表
|
||||
const attachmentList = computed(() => {
|
||||
if (!detailData.value || !detailData.value.attachment) return []
|
||||
const urls = typeof detailData.value.attachment === 'string'
|
||||
? detailData.value.attachment.split(',').filter((url: string) => url.trim())
|
||||
: []
|
||||
return urls
|
||||
})
|
||||
|
||||
// 格式化类型
|
||||
const formatType = (value: string) => {
|
||||
if (!value) return '-'
|
||||
const item = typeList.value.find((item: any) => item.value === value)
|
||||
return item ? item.label : value
|
||||
}
|
||||
|
||||
// 获取文件名
|
||||
const getFileName = (url: string): string => {
|
||||
if (!url) return '未知文件'
|
||||
return other.getQueryString(url, 'fileName') || other.getQueryString(url, 'originalFileName') || url.split('/').pop() || '未知文件'
|
||||
}
|
||||
|
||||
// 下载文件
|
||||
const handleDownload = (url: string) => {
|
||||
if (!url) return
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (id: string) => {
|
||||
visible.value = true
|
||||
detailData.value = null
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getDetail(id)
|
||||
if (res.data) {
|
||||
detailData.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取详情失败', err)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolTermDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.article-container {
|
||||
padding: 20px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.article-header {
|
||||
border-bottom: 2px solid #e4e7ed;
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.article-title {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
margin: 0 0 15px 0;
|
||||
line-height: 1.5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.article-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
padding-top: 10px;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.meta-left,
|
||||
.meta-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.article-content {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #606266;
|
||||
text-align: justify;
|
||||
word-wrap: break-word;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.article-content :deep(p) {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.article-content :deep(img) {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.article-content :deep(h1),
|
||||
.article-content :deep(h2),
|
||||
.article-content :deep(h3),
|
||||
.article-content :deep(h4),
|
||||
.article-content :deep(h5),
|
||||
.article-content :deep(h6) {
|
||||
margin: 20px 0 15px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.article-content :deep(ul),
|
||||
.article-content :deep(ol) {
|
||||
margin: 15px 0;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.article-content :deep(blockquote) {
|
||||
border-left: 4px solid #409eff;
|
||||
padding-left: 15px;
|
||||
margin: 15px 0;
|
||||
color: #909399;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.article-attachment {
|
||||
margin-top: 30px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.attachment-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.attachment-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.attachment-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.attachment-item:hover {
|
||||
background-color: #ecf5ff;
|
||||
}
|
||||
|
||||
.attachment-icon {
|
||||
font-size: 20px;
|
||||
color: #409eff;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.attachment-name {
|
||||
flex: 1;
|
||||
color: #606266;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
268
src/views/stuwork/classpaper/form.vue
Normal file
268
src/views/stuwork/classpaper/form.vue
Normal file
@@ -0,0 +1,268 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="form.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select
|
||||
v-model="form.type"
|
||||
placeholder="请选择类型"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input
|
||||
v-model="form.title"
|
||||
placeholder="请输入标题"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="发表刊物" prop="journal">
|
||||
<el-input
|
||||
v-model="form.journal"
|
||||
placeholder="请输入发表刊物"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="发表页码" prop="page">
|
||||
<el-input-number
|
||||
v-model="form.page"
|
||||
:min="0"
|
||||
placeholder="请输入发表页码"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input
|
||||
v-model="form.description"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入描述"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="附件">
|
||||
<upload-file
|
||||
v-model="form.attachment"
|
||||
:limit="5"
|
||||
:fileSize="10"
|
||||
type="simple" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassPaperFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/classpaper'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import UploadFile from '/@/components/Upload/index.vue'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const classList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([
|
||||
{ label: '德育论文', value: '0' },
|
||||
{ label: '教案', value: '1' }
|
||||
])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
classCode: '',
|
||||
type: '',
|
||||
title: '',
|
||||
journal: '',
|
||||
page: 0,
|
||||
description: '',
|
||||
attachment: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班号', trigger: 'change' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择类型', trigger: 'change' }
|
||||
],
|
||||
title: [
|
||||
{ required: true, message: '请输入标题', trigger: 'blur' }
|
||||
],
|
||||
journal: [
|
||||
{ required: true, message: '请输入发表刊物', trigger: 'blur' }
|
||||
],
|
||||
page: [
|
||||
{ required: true, message: '请输入发表页码', trigger: 'blur' }
|
||||
],
|
||||
description: [
|
||||
{ required: true, message: '请输入描述', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.classCode = ''
|
||||
form.type = ''
|
||||
form.title = ''
|
||||
form.journal = ''
|
||||
form.page = 0
|
||||
form.description = ''
|
||||
form.attachment = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.classCode = row.classCode || ''
|
||||
form.type = row.type || ''
|
||||
form.title = row.title || ''
|
||||
form.journal = row.journal || ''
|
||||
form.page = row.page || 0
|
||||
form.description = row.description || ''
|
||||
form.attachment = row.attachment || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && !row.description) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.description = res.data.description || ''
|
||||
form.attachment = res.data.attachment || ''
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
classCode: form.classCode,
|
||||
type: form.type,
|
||||
title: form.title,
|
||||
journal: form.journal,
|
||||
page: form.page,
|
||||
description: form.description,
|
||||
attachment: form.attachment || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取班号列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班号列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getClassListData()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
415
src/views/stuwork/classpaper/index.vue
Normal file
415
src/views/stuwork/classpaper/index.vue
Normal file
@@ -0,0 +1,415 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班号" prop="classNo">
|
||||
<el-select
|
||||
v-model="state.queryForm.classNo"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classNo">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input
|
||||
v-model="state.queryForm.title"
|
||||
placeholder="请输入标题"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select
|
||||
v-model="state.queryForm.type"
|
||||
placeholder="请选择类型"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="title" label="标题" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="classNo" label="班号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="teacherRealName" label="班主任" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="type" label="类型" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatType(scope.row.type) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="journal" label="发表刊物" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="page" label="发表页码" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="isAddScore" label="加分" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.isAddScore === '1' ? '是' : '否' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="attachment" label="附件" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.attachment"
|
||||
icon="Document"
|
||||
text
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleViewAttachment(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleView(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.isAddScore !== '1'"
|
||||
icon="Plus"
|
||||
text
|
||||
type="success"
|
||||
@click="handleAddScore(scope.row)">
|
||||
加分
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 查看详情弹窗 -->
|
||||
<detail-dialog ref="detailDialogRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassPaper">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, addScore } from "/@/api/stuwork/classpaper";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import FormDialog from './form.vue'
|
||||
import DetailDialog from './detail.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const detailDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([
|
||||
{ label: '德育论文', value: '0' },
|
||||
{ label: '教案', value: '1' }
|
||||
])
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
deptCode: '',
|
||||
classNo: '',
|
||||
title: '',
|
||||
type: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化类型
|
||||
const formatType = (value: string) => {
|
||||
if (!value) return '-'
|
||||
const item = typeList.value.find((item: any) => item.value === value)
|
||||
return item ? item.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.classNo = ''
|
||||
state.queryForm.title = ''
|
||||
state.queryForm.type = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 查看
|
||||
const handleView = (row: any) => {
|
||||
detailDialogRef.value?.openDialog(row.id)
|
||||
}
|
||||
|
||||
// 查看附件
|
||||
const handleViewAttachment = (row: any) => {
|
||||
if (row.attachment) {
|
||||
const urls = typeof row.attachment === 'string' ? row.attachment.split(',') : [row.attachment]
|
||||
urls.forEach((url: string) => {
|
||||
if (url.trim()) {
|
||||
window.open(url.trim(), '_blank')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 加分
|
||||
const handleAddScore = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要对该论文/案例进行加分吗?')
|
||||
await addScore({
|
||||
id: row.id,
|
||||
...row
|
||||
})
|
||||
useMessage().success('加分成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '加分失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该论文/案例吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班号列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班号列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
179
src/views/stuwork/classpublicity/belong.vue
Normal file
179
src/views/stuwork/classpublicity/belong.vue
Normal file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="归档"
|
||||
v-model="visible"
|
||||
:width="500"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="标题">
|
||||
<el-input v-model="form.title" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="作者">
|
||||
<el-input v-model="form.author" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="班号">
|
||||
<el-input v-model="form.classNo" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="归档级别" prop="belong">
|
||||
<el-select
|
||||
v-model="form.belong"
|
||||
placeholder="请选择归档级别"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in belongList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassPublicityBelongDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { editBelong, getDetail } from '/@/api/stuwork/classpublicity'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const belongList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
title: '',
|
||||
author: '',
|
||||
classNo: '',
|
||||
belong: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
belong: [
|
||||
{ required: true, message: '请选择归档级别', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.title = ''
|
||||
form.author = ''
|
||||
form.classNo = ''
|
||||
form.belong = ''
|
||||
|
||||
if (row) {
|
||||
form.id = row.id
|
||||
form.title = row.title || ''
|
||||
form.author = row.author || ''
|
||||
form.classNo = row.classNo || ''
|
||||
form.belong = row.belong || ''
|
||||
|
||||
// 如果没有归档级别,尝试获取详情
|
||||
if (row.id && !row.belong) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.belong = res.data.belong || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
await editBelong({
|
||||
id: form.id,
|
||||
belong: form.belong
|
||||
})
|
||||
useMessage().success('归档成功')
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '归档失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取归档级别字典
|
||||
const getBelongDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('public_belong_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
belongList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取归档级别字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getBelongDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
216
src/views/stuwork/classpublicity/form.vue
Normal file
216
src/views/stuwork/classpublicity/form.vue
Normal file
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="form.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="作者" prop="author">
|
||||
<el-input
|
||||
v-model="form.author"
|
||||
placeholder="请输入作者"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input
|
||||
v-model="form.title"
|
||||
placeholder="请输入标题"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="网址" prop="website">
|
||||
<el-input
|
||||
v-model="form.website"
|
||||
placeholder="请输入网址,例如:https://www.example.com"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassPublicityFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/classpublicity'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
classCode: '',
|
||||
author: '',
|
||||
title: '',
|
||||
website: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班号', trigger: 'change' }
|
||||
],
|
||||
author: [
|
||||
{ required: true, message: '请输入作者', trigger: 'blur' }
|
||||
],
|
||||
title: [
|
||||
{ required: true, message: '请输入标题', trigger: 'blur' }
|
||||
],
|
||||
website: [
|
||||
{ required: true, message: '请输入网址', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/,
|
||||
message: '请输入正确的网址格式',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.classCode = ''
|
||||
form.author = ''
|
||||
form.title = ''
|
||||
form.website = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.classCode = row.classCode || ''
|
||||
form.author = row.author || ''
|
||||
form.title = row.title || ''
|
||||
form.website = row.website || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.title || !row.website)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.website = res.data.website || ''
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
classCode: form.classCode,
|
||||
author: form.author,
|
||||
title: form.title,
|
||||
website: form.website
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取班号列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班号列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getClassListData()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
407
src/views/stuwork/classpublicity/index.vue
Normal file
407
src/views/stuwork/classpublicity/index.vue
Normal file
@@ -0,0 +1,407 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px"
|
||||
@change="handleDeptChange">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="classNo" label="班号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="title" label="标题" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="author" label="作者" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="updateTime" label="更新时间" show-overflow-tooltip align="center" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="belong" label="归档级别" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatBelong(scope.row.belong) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="isAddScore" label="加分" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.isAddScore === '1' ? '是' : '否' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="300" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleView(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.isAddScore !== '1'"
|
||||
icon="Plus"
|
||||
text
|
||||
type="success"
|
||||
@click="handleAddScore(scope.row)">
|
||||
加分
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Folder"
|
||||
text
|
||||
type="warning"
|
||||
@click="handleBelong(scope.row)">
|
||||
归档
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 归档弹窗 -->
|
||||
<belong-dialog ref="belongDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassPublicity">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, addScore } from "/@/api/stuwork/classpublicity";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
import FormDialog from './form.vue'
|
||||
import BelongDialog from './belong.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const belongDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const belongList = ref<any[]>([])
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
deptCode: '',
|
||||
classCode: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化归档级别
|
||||
const formatBelong = (value: string) => {
|
||||
if (!value) return '-'
|
||||
const item = belongList.value.find((item: any) => item.value === value)
|
||||
return item ? item.label : value
|
||||
}
|
||||
|
||||
// 学院变化
|
||||
const handleDeptChange = () => {
|
||||
// 可以根据学院筛选班级,这里暂时不实现
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.classCode = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 查看(跳转网址)
|
||||
const handleView = (row: any) => {
|
||||
if (row.website) {
|
||||
window.open(row.website, '_blank')
|
||||
} else {
|
||||
useMessage().warning('该记录没有网址')
|
||||
}
|
||||
}
|
||||
|
||||
// 加分
|
||||
const handleAddScore = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要对该班级宣传进行加分吗?')
|
||||
await addScore({
|
||||
id: row.id,
|
||||
...row
|
||||
})
|
||||
useMessage().success('加分成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '加分失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 归档
|
||||
const handleBelong = (row: any) => {
|
||||
belongDialogRef.value?.openDialog(row)
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该班级宣传吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班号列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班号列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取归档级别字典
|
||||
const getBelongDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('public_belong_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
belongList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
belongList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取归档级别字典失败', err)
|
||||
belongList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
getBelongDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
277
src/views/stuwork/classsafeedu/detail.vue
Normal file
277
src/views/stuwork/classsafeedu/detail.vue
Normal file
@@ -0,0 +1,277 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="查看详情"
|
||||
v-model="visible"
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
width="1000px">
|
||||
<div v-loading="loading" class="article-container" v-if="detailData">
|
||||
<!-- 报纸文章样式 -->
|
||||
<div class="article-header">
|
||||
<h1 class="article-title">{{ detailData.themeName || '-' }}</h1>
|
||||
<div class="article-meta">
|
||||
<div class="meta-left">
|
||||
<span class="meta-item">学年:{{ detailData.schoolYear || '-' }}</span>
|
||||
<span class="meta-item">学期:{{ formatSchoolTerm(detailData.schoolTerm) }}</span>
|
||||
<span class="meta-item">班号:{{ detailData.classNo || '-' }}</span>
|
||||
</div>
|
||||
<div class="meta-right">
|
||||
<span class="meta-item">主持人:{{ detailData.author || '-' }}</span>
|
||||
<span class="meta-item">活动地点:{{ detailData.address || '-' }}</span>
|
||||
<span class="meta-item">活动时间:{{ detailData.recordDate || '-' }}</span>
|
||||
<span class="meta-item">参加人数:{{ detailData.attendNum || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动内容 -->
|
||||
<div class="article-content" v-html="detailData.content || '-'"></div>
|
||||
|
||||
<!-- 活动图片1 -->
|
||||
<div v-if="imageList1.length > 0" class="article-images">
|
||||
<h3 class="images-title">活动照片</h3>
|
||||
<div class="images-grid">
|
||||
<el-image
|
||||
v-for="(url, index) in imageList1"
|
||||
:key="index"
|
||||
:src="url"
|
||||
:preview-src-list="imageList1"
|
||||
:initial-index="index"
|
||||
fit="cover"
|
||||
class="article-image" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动图片2 -->
|
||||
<div v-if="imageList2.length > 0" class="article-images">
|
||||
<h3 class="images-title">活动照片2</h3>
|
||||
<div class="images-grid">
|
||||
<el-image
|
||||
v-for="(url, index) in imageList2"
|
||||
:key="index"
|
||||
:src="url"
|
||||
:preview-src-list="imageList2"
|
||||
:initial-index="index"
|
||||
fit="cover"
|
||||
class="article-image" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassSafeEduDetailDialog">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { getDetail } from '/@/api/stuwork/classsafeedu'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
|
||||
// 定义变量内容
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const detailData = ref<any>({})
|
||||
const schoolTermList = ref<any[]>([])
|
||||
|
||||
// 图片列表
|
||||
const imageList1 = computed(() => {
|
||||
if (!detailData.value.attachment) return []
|
||||
const urls = typeof detailData.value.attachment === 'string'
|
||||
? detailData.value.attachment.split(',').filter((url: string) => url.trim())
|
||||
: []
|
||||
return urls
|
||||
})
|
||||
|
||||
const imageList2 = computed(() => {
|
||||
if (!detailData.value.attachment2) return []
|
||||
const urls = typeof detailData.value.attachment2 === 'string'
|
||||
? detailData.value.attachment2.split(',').filter((url: string) => url.trim())
|
||||
: []
|
||||
return urls
|
||||
})
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
visible.value = true
|
||||
detailData.value = {}
|
||||
|
||||
if (!row.id) {
|
||||
useMessage().warning('数据异常')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getDetail(row.id)
|
||||
if (res.data) {
|
||||
detailData.value = res.data
|
||||
} else {
|
||||
useMessage().error('获取详情失败')
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('获取详情失败', err)
|
||||
useMessage().error(err.msg || '获取详情失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolTermDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.article-container {
|
||||
padding: 20px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.article-header {
|
||||
border-bottom: 2px solid #e4e7ed;
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.article-title {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
margin: 0 0 15px 0;
|
||||
line-height: 1.5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.article-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
padding-top: 10px;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.meta-left,
|
||||
.meta-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.article-content {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #606266;
|
||||
text-align: justify;
|
||||
word-wrap: break-word;
|
||||
min-height: 200px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.article-content :deep(p) {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.article-content :deep(img) {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.article-content :deep(h1),
|
||||
.article-content :deep(h2),
|
||||
.article-content :deep(h3),
|
||||
.article-content :deep(h4),
|
||||
.article-content :deep(h5),
|
||||
.article-content :deep(h6) {
|
||||
margin: 20px 0 15px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.article-content :deep(ul),
|
||||
.article-content :deep(ol) {
|
||||
margin: 15px 0;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.article-content :deep(blockquote) {
|
||||
border-left: 4px solid #409eff;
|
||||
padding-left: 15px;
|
||||
margin: 15px 0;
|
||||
color: #909399;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.article-images {
|
||||
margin-top: 30px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.images-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.images-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.article-image {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.article-image:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
</style>
|
||||
|
||||
290
src/views/stuwork/classsafeedu/form.vue
Normal file
290
src/views/stuwork/classsafeedu/form.vue
Normal file
@@ -0,0 +1,290 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="900"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="form.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="活动主题" prop="themeName">
|
||||
<el-input
|
||||
v-model="form.themeName"
|
||||
placeholder="请输入活动主题"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="主持人" prop="author">
|
||||
<el-input
|
||||
v-model="form.author"
|
||||
placeholder="请输入主持人"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="活动地点" prop="address">
|
||||
<el-input
|
||||
v-model="form.address"
|
||||
placeholder="请输入活动地点"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="活动时间" prop="recordDate">
|
||||
<el-date-picker
|
||||
v-model="form.recordDate"
|
||||
type="date"
|
||||
placeholder="选择活动时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="参加人数" prop="attendNum">
|
||||
<el-input-number
|
||||
v-model="form.attendNum"
|
||||
:min="0"
|
||||
placeholder="请输入参加人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="活动内容" prop="content">
|
||||
<Editor
|
||||
v-model:getHtml="form.content"
|
||||
:height="300"
|
||||
placeholder="请输入活动内容" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="活动图片" prop="attachment">
|
||||
<upload-file
|
||||
v-model="form.attachment"
|
||||
:limit="5"
|
||||
:fileSize="10"
|
||||
type="simple" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="活动图片2" prop="attachment2">
|
||||
<upload-file
|
||||
v-model="form.attachment2"
|
||||
:limit="5"
|
||||
:fileSize="10"
|
||||
type="simple" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassSafeEduFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/classsafeedu'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import Editor from '/@/components/Editor/index.vue'
|
||||
import UploadFile from '/@/components/Upload/index.vue'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
classCode: '',
|
||||
themeName: '',
|
||||
author: '',
|
||||
address: '',
|
||||
recordDate: '',
|
||||
attendNum: 0,
|
||||
content: '',
|
||||
attachment: '',
|
||||
attachment2: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班号', trigger: 'change' }
|
||||
],
|
||||
themeName: [
|
||||
{ required: true, message: '请输入活动主题', trigger: 'blur' }
|
||||
],
|
||||
author: [
|
||||
{ required: true, message: '请输入主持人', trigger: 'blur' }
|
||||
],
|
||||
address: [
|
||||
{ required: true, message: '请输入活动地点', trigger: 'blur' }
|
||||
],
|
||||
recordDate: [
|
||||
{ required: true, message: '请选择活动时间', trigger: 'change' }
|
||||
],
|
||||
attendNum: [
|
||||
{ required: true, message: '请输入参加人数', trigger: 'blur' }
|
||||
],
|
||||
content: [
|
||||
{ required: true, message: '请输入活动内容', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.classCode = ''
|
||||
form.themeName = ''
|
||||
form.author = ''
|
||||
form.address = ''
|
||||
form.recordDate = ''
|
||||
form.attendNum = 0
|
||||
form.content = ''
|
||||
form.attachment = ''
|
||||
form.attachment2 = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.classCode = row.classCode || ''
|
||||
form.themeName = row.themeName || ''
|
||||
form.author = row.author || ''
|
||||
form.address = row.address || ''
|
||||
form.recordDate = row.recordDate || ''
|
||||
form.attendNum = row.attendNum || 0
|
||||
form.content = row.content || ''
|
||||
form.attachment = row.attachment || ''
|
||||
form.attachment2 = row.attachment2 || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && !row.content) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.content = res.data.content || ''
|
||||
form.attachment = res.data.attachment || ''
|
||||
form.attachment2 = res.data.attachment2 || ''
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
classCode: form.classCode,
|
||||
themeName: form.themeName,
|
||||
author: form.author,
|
||||
address: form.address,
|
||||
recordDate: form.recordDate,
|
||||
attendNum: form.attendNum,
|
||||
content: form.content,
|
||||
attachment: form.attachment || '',
|
||||
attachment2: form.attachment2 || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getClassListData()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
381
src/views/stuwork/classsafeedu/index.vue
Normal file
381
src/views/stuwork/classsafeedu/index.vue
Normal file
@@ -0,0 +1,381 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动时间" prop="recordDate">
|
||||
<el-date-picker
|
||||
v-model="state.queryForm.recordDate"
|
||||
type="date"
|
||||
placeholder="选择活动时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleExport">
|
||||
导出
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="classNo" label="班号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="themeName" label="活动主题" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="author" label="主持人" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="address" label="活动地点" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="recordDate" label="活动时间" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="attendNum" label="参加人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="attachment" label="活动照片" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.attachment"
|
||||
icon="Picture"
|
||||
text
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleViewImage(scope.row.attachment)">
|
||||
查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="attachment2" label="活动照片2" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.attachment2"
|
||||
icon="Picture"
|
||||
text
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleViewImage(scope.row.attachment2)">
|
||||
查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleView(scope.row)">
|
||||
查看详情
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 查看详情弹窗 -->
|
||||
<detail-dialog ref="detailDialogRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassSafeEdu">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, exportExcel } from "/@/api/stuwork/classsafeedu";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import FormDialog from './form.vue'
|
||||
import DetailDialog from './detail.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const detailDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
classCode: '',
|
||||
recordDate: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.classCode = ''
|
||||
state.queryForm.recordDate = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 查看图片
|
||||
const handleViewImage = (url: string) => {
|
||||
if (url) {
|
||||
const urls = typeof url === 'string' ? url.split(',') : [url]
|
||||
urls.forEach((imgUrl: string) => {
|
||||
if (imgUrl.trim()) {
|
||||
window.open(imgUrl.trim(), '_blank')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const res = await exportExcel(state.queryForm)
|
||||
|
||||
// 创建blob对象
|
||||
const blob = new Blob([res], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
})
|
||||
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
|
||||
// 设置文件名
|
||||
const fileName = `安全教育_${new Date().getTime()}.xlsx`
|
||||
link.setAttribute('download', fileName)
|
||||
|
||||
// 触发下载
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
|
||||
// 清理
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
|
||||
useMessage().success('导出成功')
|
||||
} catch (err: any) {
|
||||
console.error('导出失败', err)
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const handleView = (row: any) => {
|
||||
detailDialogRef.value?.openDialog(row)
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该安全教育记录吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getClassListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
239
src/views/stuwork/classsummary/detail.vue
Normal file
239
src/views/stuwork/classsummary/detail.vue
Normal file
@@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="查看详情"
|
||||
v-model="visible"
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
width="1000px">
|
||||
<div v-loading="loading" class="article-container" v-if="detailData">
|
||||
<!-- 报纸文章样式 -->
|
||||
<div class="article-header">
|
||||
<h1 class="article-title">班级总结</h1>
|
||||
<div class="article-meta">
|
||||
<div class="meta-left">
|
||||
<span class="meta-item">学年:{{ detailData.schoolYear || '-' }}</span>
|
||||
<span class="meta-item">学期:{{ formatSchoolTerm(detailData.schoolTerm) }}</span>
|
||||
<span class="meta-item">班号:{{ detailData.classNo || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计信息 -->
|
||||
<div class="summary-stats">
|
||||
<el-descriptions :column="4" border>
|
||||
<el-descriptions-item label="总人数">{{ detailData.totalCnt || 0 }}</el-descriptions-item>
|
||||
<el-descriptions-item label="男生人数">{{ detailData.boyCnt || 0 }}</el-descriptions-item>
|
||||
<el-descriptions-item label="女生人数">{{ detailData.girlCnt || 0 }}</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">
|
||||
<span>{{ formatStatus(detailData.status) }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="男(住宿)">{{ detailData.boyDormCnt || 0 }}</el-descriptions-item>
|
||||
<el-descriptions-item label="女(住宿)">{{ detailData.girlDormCnt || 0 }}</el-descriptions-item>
|
||||
<el-descriptions-item label="留校察看人数">{{ detailData.keepSchoolCnt || 0 }}</el-descriptions-item>
|
||||
<el-descriptions-item label="记过人数">{{ detailData.gigCnt || 0 }}</el-descriptions-item>
|
||||
<el-descriptions-item label="严重警告人数">{{ detailData.seriousWarningCnt || 0 }}</el-descriptions-item>
|
||||
<el-descriptions-item label="警告人数">{{ detailData.warningCnt || 0 }}</el-descriptions-item>
|
||||
<el-descriptions-item label="撤销处分人数">{{ detailData.revokeCnt || 0 }}</el-descriptions-item>
|
||||
<el-descriptions-item label="退学人数">{{ detailData.dropCnt || 0 }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<!-- 总结报告 -->
|
||||
<div class="article-content">
|
||||
<h3 class="content-title">总结报告</h3>
|
||||
<div v-html="detailData.summary || '-'"></div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassSummaryDetailDialog">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getDetail } from '/@/api/stuwork/classsummary'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
// 定义变量内容
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const detailData = ref<any>(null)
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const statusList = ref<any[]>([])
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化状态
|
||||
const formatStatus = (value: string) => {
|
||||
if (!value) return '-'
|
||||
const item = statusList.value.find((item: any) => item.value === value)
|
||||
return item ? item.label : value
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (id: string) => {
|
||||
visible.value = true
|
||||
detailData.value = null
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getDetail(id)
|
||||
if (res.data) {
|
||||
detailData.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取详情失败', err)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取状态字典
|
||||
const getStatusDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('status_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
statusList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取状态字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolTermDict()
|
||||
getStatusDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.article-container {
|
||||
padding: 20px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.article-header {
|
||||
border-bottom: 2px solid #e4e7ed;
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.article-title {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
margin: 0 0 15px 0;
|
||||
line-height: 1.5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.article-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
padding-top: 10px;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.meta-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.summary-stats {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.content-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.article-content {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #606266;
|
||||
text-align: justify;
|
||||
word-wrap: break-word;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.article-content :deep(p) {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.article-content :deep(img) {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.article-content :deep(h1),
|
||||
.article-content :deep(h2),
|
||||
.article-content :deep(h3),
|
||||
.article-content :deep(h4),
|
||||
.article-content :deep(h5),
|
||||
.article-content :deep(h6) {
|
||||
margin: 20px 0 15px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.article-content :deep(ul),
|
||||
.article-content :deep(ol) {
|
||||
margin: 15px 0;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.article-content :deep(blockquote) {
|
||||
border-left: 4px solid #409eff;
|
||||
padding-left: 15px;
|
||||
margin: 15px 0;
|
||||
color: #909399;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
|
||||
355
src/views/stuwork/classsummary/form.vue
Normal file
355
src/views/stuwork/classsummary/form.vue
Normal file
@@ -0,0 +1,355 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="form.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="总人数" prop="totalCnt">
|
||||
<el-input-number
|
||||
v-model="form.totalCnt"
|
||||
:min="0"
|
||||
placeholder="请输入总人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="男生人数" prop="boyCnt">
|
||||
<el-input-number
|
||||
v-model="form.boyCnt"
|
||||
:min="0"
|
||||
placeholder="请输入男生人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="女生人数" prop="girlCnt">
|
||||
<el-input-number
|
||||
v-model="form.girlCnt"
|
||||
:min="0"
|
||||
placeholder="请输入女生人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="男(住宿)" prop="boyDormCnt">
|
||||
<el-input-number
|
||||
v-model="form.boyDormCnt"
|
||||
:min="0"
|
||||
placeholder="请输入男(住宿)人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="女(住宿)" prop="girlDormCnt">
|
||||
<el-input-number
|
||||
v-model="form.girlDormCnt"
|
||||
:min="0"
|
||||
placeholder="请输入女(住宿)人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="留校察看人数" prop="keepSchoolCnt">
|
||||
<el-input-number
|
||||
v-model="form.keepSchoolCnt"
|
||||
:min="0"
|
||||
placeholder="请输入留校察看人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="记过人数" prop="gigCnt">
|
||||
<el-input-number
|
||||
v-model="form.gigCnt"
|
||||
:min="0"
|
||||
placeholder="请输入记过人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="严重警告人数" prop="seriousWarningCnt">
|
||||
<el-input-number
|
||||
v-model="form.seriousWarningCnt"
|
||||
:min="0"
|
||||
placeholder="请输入严重警告人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="警告人数" prop="warningCnt">
|
||||
<el-input-number
|
||||
v-model="form.warningCnt"
|
||||
:min="0"
|
||||
placeholder="请输入警告人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="撤销处分人数" prop="revokeCnt">
|
||||
<el-input-number
|
||||
v-model="form.revokeCnt"
|
||||
:min="0"
|
||||
placeholder="请输入撤销处分人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="退学人数" prop="dropCnt">
|
||||
<el-input-number
|
||||
v-model="form.dropCnt"
|
||||
:min="0"
|
||||
placeholder="请输入退学人数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="总结报告" prop="summary">
|
||||
<Editor
|
||||
v-model:getHtml="form.summary"
|
||||
:height="'400'"
|
||||
placeholder="请输入总结报告" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassSummaryFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/classsummary'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import Editor from '/@/components/Editor/index.vue'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
classCode: '',
|
||||
totalCnt: 0,
|
||||
boyCnt: 0,
|
||||
girlCnt: 0,
|
||||
boyDormCnt: 0,
|
||||
girlDormCnt: 0,
|
||||
keepSchoolCnt: 0,
|
||||
gigCnt: 0,
|
||||
seriousWarningCnt: 0,
|
||||
warningCnt: 0,
|
||||
revokeCnt: 0,
|
||||
dropCnt: 0,
|
||||
summary: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班号', trigger: 'change' }
|
||||
],
|
||||
totalCnt: [
|
||||
{ required: true, message: '请输入总人数', trigger: 'blur' }
|
||||
],
|
||||
boyCnt: [
|
||||
{ required: true, message: '请输入男生人数', trigger: 'blur' }
|
||||
],
|
||||
girlCnt: [
|
||||
{ required: true, message: '请输入女生人数', trigger: 'blur' }
|
||||
],
|
||||
boyDormCnt: [
|
||||
{ required: true, message: '请输入男(住宿)人数', trigger: 'blur' }
|
||||
],
|
||||
girlDormCnt: [
|
||||
{ required: true, message: '请输入女(住宿)人数', trigger: 'blur' }
|
||||
],
|
||||
keepSchoolCnt: [
|
||||
{ required: true, message: '请输入留校察看人数', trigger: 'blur' }
|
||||
],
|
||||
gigCnt: [
|
||||
{ required: true, message: '请输入记过人数', trigger: 'blur' }
|
||||
],
|
||||
seriousWarningCnt: [
|
||||
{ required: true, message: '请输入严重警告人数', trigger: 'blur' }
|
||||
],
|
||||
warningCnt: [
|
||||
{ required: true, message: '请输入警告人数', trigger: 'blur' }
|
||||
],
|
||||
revokeCnt: [
|
||||
{ required: true, message: '请输入撤销处分人数', trigger: 'blur' }
|
||||
],
|
||||
dropCnt: [
|
||||
{ required: true, message: '请输入退学人数', trigger: 'blur' }
|
||||
],
|
||||
summary: [
|
||||
{ required: true, message: '请输入总结报告', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.classCode = ''
|
||||
form.totalCnt = 0
|
||||
form.boyCnt = 0
|
||||
form.girlCnt = 0
|
||||
form.boyDormCnt = 0
|
||||
form.girlDormCnt = 0
|
||||
form.keepSchoolCnt = 0
|
||||
form.gigCnt = 0
|
||||
form.seriousWarningCnt = 0
|
||||
form.warningCnt = 0
|
||||
form.revokeCnt = 0
|
||||
form.dropCnt = 0
|
||||
form.summary = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.classCode = row.classCode || ''
|
||||
form.totalCnt = row.totalCnt || 0
|
||||
form.boyCnt = row.boyCnt || 0
|
||||
form.girlCnt = row.girlCnt || 0
|
||||
form.boyDormCnt = row.boyDormCnt || 0
|
||||
form.girlDormCnt = row.girlDormCnt || 0
|
||||
form.keepSchoolCnt = row.keepSchoolCnt || 0
|
||||
form.gigCnt = row.gigCnt || 0
|
||||
form.seriousWarningCnt = row.seriousWarningCnt || 0
|
||||
form.warningCnt = row.warningCnt || 0
|
||||
form.revokeCnt = row.revokeCnt || 0
|
||||
form.dropCnt = row.dropCnt || 0
|
||||
form.summary = row.summary || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && !row.summary) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.summary = res.data.summary || ''
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
classCode: form.classCode,
|
||||
totalCnt: form.totalCnt,
|
||||
boyCnt: form.boyCnt,
|
||||
girlCnt: form.girlCnt,
|
||||
boyDormCnt: form.boyDormCnt,
|
||||
girlDormCnt: form.girlDormCnt,
|
||||
keepSchoolCnt: form.keepSchoolCnt,
|
||||
gigCnt: form.gigCnt,
|
||||
seriousWarningCnt: form.seriousWarningCnt,
|
||||
warningCnt: form.warningCnt,
|
||||
revokeCnt: form.revokeCnt,
|
||||
dropCnt: form.dropCnt,
|
||||
summary: form.summary
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取班号列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班号列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getClassListData()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
371
src/views/stuwork/classsummary/index.vue
Normal file
371
src/views/stuwork/classsummary/index.vue
Normal file
@@ -0,0 +1,371 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开课部门" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择开课部门"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班号" prop="classNo">
|
||||
<el-select
|
||||
v-model="state.queryForm.classNo"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classNo">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select
|
||||
v-model="state.queryForm.status"
|
||||
placeholder="请选择状态"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in statusList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="classNo" label="班号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="totalCnt" label="总人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="boyCnt" label="男生人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="girlCnt" label="女生人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="boyDormCnt" label="男(住宿)" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="girlDormCnt" label="女(住宿)" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="keepSchoolCnt" label="留校察看人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="gigCnt" label="记过人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="seriousWarningCnt" label="严重警告人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="warningCnt" label="警告人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="revokeCnt" label="撤销处分人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="dropCnt" label="退学人数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="status" label="状态" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatStatus(scope.row.status) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleView(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 查看详情弹窗 -->
|
||||
<detail-dialog ref="detailDialogRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassSummary">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/classsummary";
|
||||
import { getTeachDept } from "/@/api/basic/basicdept";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import FormDialog from './form.vue'
|
||||
import DetailDialog from './detail.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const detailDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const statusList = ref<any[]>([])
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
deptCode: '',
|
||||
classNo: '',
|
||||
status: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化状态
|
||||
const formatStatus = (value: string) => {
|
||||
if (!value) return '-'
|
||||
const item = statusList.value.find((item: any) => item.value === value)
|
||||
return item ? item.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.classNo = ''
|
||||
state.queryForm.status = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 查看
|
||||
const handleView = (row: any) => {
|
||||
detailDialogRef.value?.openDialog(row.id)
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该班级总结吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取开课部门列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getTeachDept()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取开课部门列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班号列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班号列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取状态字典
|
||||
const getStatusDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('status_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
statusList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
statusList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取状态字典失败', err)
|
||||
statusList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
getStatusDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
344
src/views/stuwork/classtheme/index.vue
Normal file
344
src/views/stuwork/classtheme/index.vue
Normal file
@@ -0,0 +1,344 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否达标" prop="isDb">
|
||||
<el-select
|
||||
v-model="state.queryForm.isDb"
|
||||
placeholder="请选择是否达标"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in yesNoList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classNo">
|
||||
<el-select
|
||||
v-model="state.queryForm.classNo"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classNo">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleInit">
|
||||
初始化
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="classNo" label="班级" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="count" label="上传次数" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="remarks" label="备注" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleViewRecord(scope.row)">
|
||||
查看上传记录
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 初始化弹窗 -->
|
||||
<init-dialog ref="initDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 查看上传记录弹窗 -->
|
||||
<record-dialog ref="recordDialogRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassTheme">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/classtheme";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import InitDialog from './init.vue'
|
||||
import RecordDialog from './record.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const initDialogRef = ref()
|
||||
const recordDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const yesNoList = ref<any[]>([])
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
isDb: '',
|
||||
deptCode: '',
|
||||
classNo: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.isDb = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.classNo = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 初始化
|
||||
const handleInit = () => {
|
||||
initDialogRef.value?.openDialog()
|
||||
}
|
||||
|
||||
// 查看上传记录
|
||||
const handleViewRecord = (row: any) => {
|
||||
recordDialogRef.value?.openDialog(row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该主题班会课教案吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取是否字典
|
||||
const getYesNoDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('yes_no')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
yesNoList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
yesNoList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取是否字典失败', err)
|
||||
yesNoList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
getYesNoDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
240
src/views/stuwork/classtheme/init.vue
Normal file
240
src/views/stuwork/classtheme/init.vue
Normal file
@@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="初始化"
|
||||
v-model="visible"
|
||||
:width="600"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="form.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="form.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="form.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="班级" prop="classNo">
|
||||
<el-select
|
||||
v-model="form.classNo"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classNo">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassThemeInitDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { initObj } from '/@/api/stuwork/classtheme'
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import { getDeptList } from '/@/api/basic/basicclass'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
deptCode: '',
|
||||
classNo: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
schoolYear: [
|
||||
{ required: true, message: '请选择学年', trigger: 'change' }
|
||||
],
|
||||
schoolTerm: [
|
||||
{ required: true, message: '请选择学期', trigger: 'change' }
|
||||
],
|
||||
deptCode: [
|
||||
{ required: true, message: '请选择学院', trigger: 'change' }
|
||||
],
|
||||
classNo: [
|
||||
{ required: true, message: '请选择班级', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
visible.value = true
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.schoolYear = ''
|
||||
form.schoolTerm = ''
|
||||
form.deptCode = ''
|
||||
form.classNo = ''
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
await initObj(form)
|
||||
useMessage().success('初始化成功')
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '初始化失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
227
src/views/stuwork/classtheme/record.vue
Normal file
227
src/views/stuwork/classtheme/record.vue
Normal file
@@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="查看上传记录"
|
||||
v-model="visible"
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
width="1000px">
|
||||
<!-- 搜索表单 -->
|
||||
<el-form :model="queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getRecordList" style="margin-bottom: 20px;">
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input
|
||||
v-model="queryForm.title"
|
||||
placeholder="请输入标题"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getRecordList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div style="margin-bottom: 20px;">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
@click="handleAdd">
|
||||
新增
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<el-table
|
||||
:data="recordList"
|
||||
border
|
||||
style="width: 100%">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="title" label="活动主题" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="fileUrl" label="附件" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.fileUrl"
|
||||
icon="Document"
|
||||
text
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleViewFile(scope.row.fileUrl)">
|
||||
查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="上传时间" show-overflow-tooltip align="center" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createBy" label="上传人" show-overflow-tooltip align="center" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-if="pagination.total > 0"
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="pagination" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" :current-row="currentRow" @refresh="getRecordList" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassThemeRecordDialog">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { fetchRecordList, delRecord } from '/@/api/stuwork/classtheme'
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||
import { parseTime } from '/@/utils/formatTime'
|
||||
import FormDialog from './recordForm.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const formDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const recordList = ref<any[]>([])
|
||||
const currentRow = ref<any>(null)
|
||||
const queryForm = reactive({
|
||||
title: ''
|
||||
})
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
// 查看文件
|
||||
const handleViewFile = (url: string) => {
|
||||
if (url) {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
queryForm.title = ''
|
||||
pagination.current = 1
|
||||
getRecordList()
|
||||
}
|
||||
|
||||
// 新增
|
||||
const handleAdd = () => {
|
||||
formDialogRef.value?.openDialog('add')
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该上传记录吗?')
|
||||
await delRecord([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getRecordList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
visible.value = true
|
||||
currentRow.value = row
|
||||
recordList.value = []
|
||||
queryForm.title = ''
|
||||
pagination.current = 1
|
||||
pagination.total = 0
|
||||
|
||||
if (row) {
|
||||
await getRecordList()
|
||||
}
|
||||
}
|
||||
|
||||
// 获取上传记录列表
|
||||
const getRecordList = async () => {
|
||||
if (!currentRow.value) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await fetchRecordList({
|
||||
schoolYear: currentRow.value.schoolYear,
|
||||
schoolTerm: currentRow.value.schoolTerm,
|
||||
deptCode: currentRow.value.deptCode,
|
||||
classNo: currentRow.value.classNo,
|
||||
title: queryForm.title,
|
||||
current: pagination.current,
|
||||
size: pagination.size
|
||||
})
|
||||
|
||||
if (res.data && res.data.records) {
|
||||
recordList.value = res.data.records
|
||||
pagination.total = res.data.total || 0
|
||||
} else {
|
||||
recordList.value = []
|
||||
pagination.total = 0
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取上传记录失败', err)
|
||||
recordList.value = []
|
||||
pagination.total = 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 分页大小改变
|
||||
const sizeChangeHandle = (size: number) => {
|
||||
pagination.size = size
|
||||
pagination.current = 1
|
||||
getRecordList()
|
||||
}
|
||||
|
||||
// 当前页改变
|
||||
const currentChangeHandle = (current: number) => {
|
||||
pagination.current = current
|
||||
getRecordList()
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
199
src/views/stuwork/classtheme/recordForm.vue
Normal file
199
src/views/stuwork/classtheme/recordForm.vue
Normal file
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input
|
||||
v-model="form.title"
|
||||
placeholder="请输入标题"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="附件上传">
|
||||
<upload-file
|
||||
v-model="form.fileUrl"
|
||||
:limit="5"
|
||||
:fileSize="10"
|
||||
type="simple" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="内容" prop="content">
|
||||
<Editor
|
||||
v-model:getHtml="form.content"
|
||||
:height="'400'"
|
||||
placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入备注"
|
||||
:maxlength="250"
|
||||
show-word-limit
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassThemeRecordFormDialog">
|
||||
import { ref, reactive, nextTick, computed } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addRecord, editRecord, getRecordDetail } from '/@/api/stuwork/classtheme'
|
||||
import Editor from '/@/components/Editor/index.vue'
|
||||
import UploadFile from '/@/components/Upload/index.vue'
|
||||
|
||||
const props = defineProps({
|
||||
currentRow: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
title: '',
|
||||
fileUrl: '',
|
||||
content: '',
|
||||
remarks: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
title: [
|
||||
{ required: true, message: '请输入标题', trigger: 'blur' }
|
||||
],
|
||||
content: [
|
||||
{ required: true, message: '请输入内容', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.title = ''
|
||||
form.fileUrl = ''
|
||||
form.content = ''
|
||||
form.remarks = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.title = row.title || ''
|
||||
form.fileUrl = row.fileUrl || ''
|
||||
form.content = row.content || ''
|
||||
form.remarks = row.remarks || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && !row.content) {
|
||||
loading.value = true
|
||||
getRecordDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.content = res.data.content || ''
|
||||
form.fileUrl = res.data.fileUrl || ''
|
||||
form.remarks = res.data.remarks || ''
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
if (!props.currentRow) {
|
||||
useMessage().error('缺少必要信息')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
title: form.title,
|
||||
fileUrl: form.fileUrl || '',
|
||||
content: form.content,
|
||||
remarks: form.remarks || '',
|
||||
schoolYear: props.currentRow.schoolYear,
|
||||
schoolTerm: props.currentRow.schoolTerm,
|
||||
deptCode: props.currentRow.deptCode,
|
||||
classNo: props.currentRow.classNo
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addRecord(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editRecord({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
style="width: 200px"
|
||||
@change="handleDeptChange">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
@@ -27,7 +28,7 @@
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
v-for="item in filteredClassList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
@@ -48,7 +49,7 @@
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
@@ -72,12 +73,12 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip align="center" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.createTime ? scope.row.createTime.split(' ')[0] + ' ' + scope.row.createTime.split(' ')[1] : '-' }}</span>
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="updateTime" label="更新时间" show-overflow-tooltip align="center" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.updateTime ? scope.row.updateTime.split(' ')[0] + ' ' + scope.row.updateTime.split(' ')[1] : '-' }}</span>
|
||||
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
@@ -103,12 +104,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="PendingWork">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { reactive, ref, onMounted, computed } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList } from "/@/api/stuwork/pendingwork";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
@@ -154,6 +156,11 @@ const handleReset = () => {
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 学院变化时,清空班级选择并过滤班级列表
|
||||
const handleDeptChange = () => {
|
||||
searchForm.classCode = ''
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const handleView = (row: any) => {
|
||||
useMessage().warning('查看详情功能待实现')
|
||||
@@ -179,6 +186,8 @@ const getClassListData = async () => {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data) {
|
||||
classList.value = Array.isArray(res.data) ? res.data : []
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
@@ -186,6 +195,14 @@ const getClassListData = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 根据学院过滤班级列表
|
||||
const filteredClassList = computed(() => {
|
||||
if (!searchForm.deptCode) {
|
||||
return classList.value
|
||||
}
|
||||
return classList.value.filter((item: any) => item.deptCode === searchForm.deptCode)
|
||||
})
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getDeptListData()
|
||||
@@ -193,3 +210,6 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
|
||||
210
src/views/stuwork/rewardclass/form.vue
Normal file
210
src/views/stuwork/rewardclass/form.vue
Normal file
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑文明班级' : '新增文明班级'"
|
||||
v-model="visible"
|
||||
:width="600"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="100px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="班号" prop="classCode">
|
||||
<el-select
|
||||
v-model="form.classCode"
|
||||
placeholder="请选择班号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
@change="handleClassChange">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="奖项名称" prop="ruleName">
|
||||
<el-input
|
||||
v-model="form.ruleName"
|
||||
placeholder="请输入奖项名称"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入备注"
|
||||
:maxlength="250"
|
||||
show-word-limit
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RewardClassFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/rewardclass'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
classCode: '',
|
||||
ruleId: '',
|
||||
ruleName: '',
|
||||
remarks: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班号', trigger: 'change' }
|
||||
],
|
||||
ruleName: [
|
||||
{ required: true, message: '请输入奖项名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.classCode = ''
|
||||
form.ruleId = ''
|
||||
form.ruleName = ''
|
||||
form.remarks = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.classCode = row.classCode || ''
|
||||
form.ruleId = row.ruleId || ''
|
||||
form.ruleName = row.ruleName || ''
|
||||
form.remarks = row.remarks || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.ruleName || !row.remarks)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.classCode = res.data.classCode || ''
|
||||
form.ruleId = res.data.ruleId || ''
|
||||
form.ruleName = res.data.ruleName || ''
|
||||
form.remarks = res.data.remarks || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 班级变化
|
||||
const handleClassChange = () => {
|
||||
// 可以根据班级获取相关信息,这里暂时不实现
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
classCode: form.classCode,
|
||||
ruleId: form.ruleId || '', // 如果没有ruleId,传空字符串
|
||||
ruleName: form.ruleName,
|
||||
remarks: form.remarks || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getClassListData()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
424
src/views/stuwork/rewardclass/index.vue
Normal file
424
src/views/stuwork/rewardclass/index.vue
Normal file
@@ -0,0 +1,424 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px"
|
||||
@change="handleDeptChange">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Upload"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleImport">
|
||||
导入
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="classNo" label="班级" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="classMasterName" label="班主任" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="ruleName" label="奖项名称" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="remarks" label="备注" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 导入弹窗 -->
|
||||
<el-dialog
|
||||
title="导入文明班级"
|
||||
v-model="importDialogVisible"
|
||||
:width="500"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<div style="margin-bottom: 15px;">
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="success"
|
||||
@click="handleDownloadTemplate">
|
||||
下载模板
|
||||
</el-button>
|
||||
</div>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:auto-upload="false"
|
||||
:on-change="handleFileChange"
|
||||
:limit="1"
|
||||
accept=".xlsx,.xls"
|
||||
drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
只能上传 xlsx/xls 文件
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="importDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :disabled="!importFile || importLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RewardClass">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, importExcel } from "/@/api/stuwork/rewardclass";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { UploadFilled } from '@element-plus/icons-vue'
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const uploadRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const importDialogVisible = ref(false)
|
||||
const importFile = ref<File | null>(null)
|
||||
const importLoading = ref(false)
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
deptCode: '',
|
||||
classCode: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 学院变化
|
||||
const handleDeptChange = () => {
|
||||
// 可以根据学院筛选班级,这里暂时不实现
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.classCode = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 导入
|
||||
const handleImport = () => {
|
||||
importDialogVisible.value = true
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
}
|
||||
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
try {
|
||||
const fileName = '文明班级导入模板.xlsx'
|
||||
// 使用动态导入获取文件URL,从 views/stuwork/rewardclass 到 assets/file 的相对路径
|
||||
const fileUrl = new URL(`../../../assets/file/${fileName}`, import.meta.url).href
|
||||
const response = await fetch(fileUrl)
|
||||
if (!response.ok) {
|
||||
throw new Error('文件下载失败')
|
||||
}
|
||||
const blob = await response.blob()
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = fileName
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
window.URL.revokeObjectURL(url)
|
||||
document.body.removeChild(link)
|
||||
useMessage().success('模板下载成功')
|
||||
} catch (error) {
|
||||
console.error('模板下载失败', error)
|
||||
useMessage().error('模板下载失败,请检查模板文件是否存在')
|
||||
}
|
||||
}
|
||||
|
||||
// 文件变化
|
||||
const handleFileChange = (file: any) => {
|
||||
importFile.value = file.raw
|
||||
}
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (!importFile.value) {
|
||||
useMessage().warning('请选择要导入的文件')
|
||||
return
|
||||
}
|
||||
|
||||
importLoading.value = true
|
||||
try {
|
||||
await importExcel(importFile.value)
|
||||
useMessage().success('导入成功')
|
||||
importDialogVisible.value = false
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败')
|
||||
} finally {
|
||||
importLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该文明班级记录吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
204
src/views/stuwork/rewarddorm/form.vue
Normal file
204
src/views/stuwork/rewarddorm/form.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑文明宿舍' : '新增文明宿舍'"
|
||||
v-model="visible"
|
||||
:width="600"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="100px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="宿舍号" prop="roomNo">
|
||||
<el-select
|
||||
v-model="form.roomNo"
|
||||
placeholder="请选择宿舍号"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in roomList"
|
||||
:key="item.roomNo"
|
||||
:label="item.roomNo"
|
||||
:value="item.roomNo">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="奖项名称" prop="ruleName">
|
||||
<el-input
|
||||
v-model="form.ruleName"
|
||||
placeholder="请输入奖项名称"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入备注"
|
||||
:maxlength="250"
|
||||
show-word-limit
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RewardDormFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/rewarddorm'
|
||||
import { dormRoomList } from '/@/api/stuwork/dormroom'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const roomList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
roomNo: '',
|
||||
ruleId: '',
|
||||
ruleName: '',
|
||||
remarks: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
roomNo: [
|
||||
{ required: true, message: '请选择宿舍号', trigger: 'change' }
|
||||
],
|
||||
ruleName: [
|
||||
{ required: true, message: '请输入奖项名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.roomNo = ''
|
||||
form.ruleId = ''
|
||||
form.ruleName = ''
|
||||
form.remarks = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.roomNo = row.roomNo || ''
|
||||
form.ruleId = row.ruleId || ''
|
||||
form.ruleName = row.ruleName || ''
|
||||
form.remarks = row.remarks || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.ruleName || !row.remarks)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.roomNo = res.data.roomNo || ''
|
||||
form.ruleId = res.data.ruleId || ''
|
||||
form.ruleName = res.data.ruleName || ''
|
||||
form.remarks = res.data.remarks || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
roomNo: form.roomNo,
|
||||
ruleId: form.ruleId || '', // 如果没有ruleId,传空字符串
|
||||
ruleName: form.ruleName,
|
||||
remarks: form.remarks || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取宿舍列表
|
||||
const getRoomListData = async () => {
|
||||
try {
|
||||
const res = await dormRoomList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
roomList.value = res.data
|
||||
} else {
|
||||
roomList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取宿舍列表失败', err)
|
||||
roomList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getRoomListData()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
364
src/views/stuwork/rewarddorm/index.vue
Normal file
364
src/views/stuwork/rewarddorm/index.vue
Normal file
@@ -0,0 +1,364 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="宿舍号" prop="roomNo">
|
||||
<el-input
|
||||
v-model="state.queryForm.roomNo"
|
||||
placeholder="请输入宿舍号"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="奖项名称" prop="ruleName">
|
||||
<el-input
|
||||
v-model="state.queryForm.ruleName"
|
||||
placeholder="请输入奖项名称"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Upload"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleImport">
|
||||
导入
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="roomNo" label="宿舍号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="ruleName" label="奖项名称" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="remarks" label="备注" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 导入弹窗 -->
|
||||
<el-dialog
|
||||
title="导入文明宿舍"
|
||||
v-model="importDialogVisible"
|
||||
:width="500"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<div style="margin-bottom: 15px;">
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="success"
|
||||
@click="handleDownloadTemplate">
|
||||
下载模板
|
||||
</el-button>
|
||||
</div>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:auto-upload="false"
|
||||
:on-change="handleFileChange"
|
||||
:limit="1"
|
||||
accept=".xlsx,.xls"
|
||||
drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
只能上传 xlsx/xls 文件
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="importDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :disabled="!importFile || importLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RewardDorm">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, importExcel } from "/@/api/stuwork/rewarddorm";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { UploadFilled } from '@element-plus/icons-vue'
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const uploadRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const importDialogVisible = ref(false)
|
||||
const importFile = ref<File | null>(null)
|
||||
const importLoading = ref(false)
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
roomNo: '',
|
||||
ruleName: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.roomNo = ''
|
||||
state.queryForm.ruleName = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 导入
|
||||
const handleImport = () => {
|
||||
importDialogVisible.value = true
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
}
|
||||
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
try {
|
||||
const fileName = '文明宿舍导入模板.xlsx'
|
||||
// 使用动态导入获取文件URL,从 views/stuwork/rewarddorm 到 assets/file 的相对路径
|
||||
const fileUrl = new URL(`../../../assets/file/${fileName}`, import.meta.url).href
|
||||
const response = await fetch(fileUrl)
|
||||
if (!response.ok) {
|
||||
throw new Error('文件下载失败')
|
||||
}
|
||||
const blob = await response.blob()
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = fileName
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
window.URL.revokeObjectURL(url)
|
||||
document.body.removeChild(link)
|
||||
useMessage().success('模板下载成功')
|
||||
} catch (error) {
|
||||
console.error('模板下载失败', error)
|
||||
useMessage().error('模板下载失败,请检查模板文件是否存在')
|
||||
}
|
||||
}
|
||||
|
||||
// 文件变化
|
||||
const handleFileChange = (file: any) => {
|
||||
importFile.value = file.raw
|
||||
}
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (!importFile.value) {
|
||||
useMessage().warning('请选择要导入的文件')
|
||||
return
|
||||
}
|
||||
|
||||
importLoading.value = true
|
||||
try {
|
||||
await importExcel(importFile.value)
|
||||
useMessage().success('导入成功')
|
||||
importDialogVisible.value = false
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败')
|
||||
} finally {
|
||||
importLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该文明宿舍记录吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
201
src/views/stuwork/rewardrule/form.vue
Normal file
201
src/views/stuwork/rewardrule/form.vue
Normal file
@@ -0,0 +1,201 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑评优评先奖项' : '新增评优评先奖项'"
|
||||
v-model="visible"
|
||||
:width="600"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="100px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="奖项名称" prop="ruleName">
|
||||
<el-input
|
||||
v-model="form.ruleName"
|
||||
placeholder="请输入奖项名称"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="奖项类型" prop="ruleType">
|
||||
<el-select
|
||||
v-model="form.ruleType"
|
||||
placeholder="请选择奖项类型"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in ruleTypeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入备注"
|
||||
:maxlength="250"
|
||||
show-word-limit
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RewardRuleFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/rewardrule'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const ruleTypeList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
ruleName: '',
|
||||
ruleType: '',
|
||||
remarks: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
ruleName: [
|
||||
{ required: true, message: '请输入奖项名称', trigger: 'blur' }
|
||||
],
|
||||
ruleType: [
|
||||
{ required: true, message: '请选择奖项类型', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.ruleName = ''
|
||||
form.ruleType = ''
|
||||
form.remarks = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.ruleName = row.ruleName || ''
|
||||
form.ruleType = row.ruleType || ''
|
||||
form.remarks = row.remarks || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.ruleName || !row.ruleType)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.ruleName = res.data.ruleName || ''
|
||||
form.ruleType = res.data.ruleType || ''
|
||||
form.remarks = res.data.remarks || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
ruleName: form.ruleName,
|
||||
ruleType: form.ruleType,
|
||||
remarks: form.remarks || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取奖项类型字典
|
||||
const getRuleTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('rule_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
ruleTypeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
ruleTypeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取奖项类型字典失败', err)
|
||||
ruleTypeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getRuleTypeDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
197
src/views/stuwork/rewardrule/index.vue
Normal file
197
src/views/stuwork/rewardrule/index.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="奖项类型" prop="ruleType">
|
||||
<el-select
|
||||
v-model="state.queryForm.ruleType"
|
||||
placeholder="请选择奖项类型"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in ruleTypeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="ruleName" label="奖项名称" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="ruleType" label="奖项类型" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatRuleType(scope.row.ruleType) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remarks" label="备注" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RewardRule">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/rewardrule";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const ruleTypeList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
ruleType: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化奖项类型
|
||||
const formatRuleType = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = ruleTypeList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.ruleType = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该评优评先奖项吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取奖项类型字典
|
||||
const getRuleTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('rule_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
ruleTypeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
ruleTypeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取奖项类型字典失败', err)
|
||||
ruleTypeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getRuleTypeDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
317
src/views/stuwork/rewardstudent/index.vue
Normal file
317
src/views/stuwork/rewardstudent/index.vue
Normal file
@@ -0,0 +1,317 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleExport">
|
||||
导出
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="dataList"
|
||||
v-loading="loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="departName" label="学院" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="classNo" label="班级" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="stuNo" label="学号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="averageConduct" label="操行平均分" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.averageConduct !== null && scope.row.averageConduct !== undefined ? scope.row.averageConduct.toFixed(2) : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="averageScore" label="总评成绩平均分" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.averageScore !== null && scope.row.averageScore !== undefined ? scope.row.averageScore.toFixed(2) : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="violation" label="违规情况" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="ruleName" label="个人奖项" show-overflow-tooltip align="center" min-width="200">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.ruleName && Array.isArray(scope.row.ruleName) && scope.row.ruleName.length > 0">
|
||||
{{ scope.row.ruleName.join('、') }}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="upDateTime" label="保存时间" show-overflow-tooltip align="center" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.upDateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RewardStudent">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { fetchList, exportExcel } from "/@/api/stuwork/rewardstudent";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const loading = ref(false)
|
||||
const dataList = ref<any[]>([])
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 查询表单
|
||||
const queryForm = reactive({
|
||||
deptCode: '',
|
||||
classCode: '',
|
||||
schoolYear: '',
|
||||
schoolTerm: ''
|
||||
})
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 获取数据列表
|
||||
const getDataList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await fetchList(queryForm)
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
dataList.value = res.data
|
||||
} else {
|
||||
dataList.value = []
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('获取数据列表失败', err)
|
||||
useMessage().error(err.msg || '获取数据列表失败')
|
||||
dataList.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
queryForm.deptCode = ''
|
||||
queryForm.classCode = ''
|
||||
queryForm.schoolYear = ''
|
||||
queryForm.schoolTerm = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
const res = await exportExcel(queryForm)
|
||||
|
||||
// 创建blob对象
|
||||
const blob = new Blob([res], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
})
|
||||
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
|
||||
// 设置文件名
|
||||
const fileName = `学生评优评先_${new Date().getTime()}.xlsx`
|
||||
link.setAttribute('download', fileName)
|
||||
|
||||
// 触发下载
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
|
||||
// 清理
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
|
||||
useMessage().success('导出成功')
|
||||
} catch (err: any) {
|
||||
console.error('导出失败', err)
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
getDataList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
322
src/views/stuwork/stipendstu/examIndex.vue
Normal file
322
src/views/stuwork/stipendstu/examIndex.vue
Normal file
@@ -0,0 +1,322 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleAdd">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="title" label="批次名称" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" label="季度" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatQuarter(scope.row.type) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="classify" label="类别" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatClassify(scope.row.classify) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="moneyValue" label="补助金额" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.moneyValue !== undefined && scope.row.moneyValue !== null ? scope.row.moneyValue : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="startTime" label="开始日期" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="endTime" label="截止日期" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remarks" label="备注" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StipendTermBatch">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/stipendtermbatch";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
const formDialogRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const quarterList = ref<any[]>([])
|
||||
const classifyList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化季度
|
||||
const formatQuarter = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = quarterList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化类别
|
||||
const formatClassify = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = classifyList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 新增
|
||||
const handleAdd = () => {
|
||||
formDialogRef.value?.openDialog('add')
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row.id)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
try {
|
||||
const { confirm } = useMessageBox()
|
||||
await confirm(`确定要删除批次 "${row.title}" 吗?`)
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取季度字典
|
||||
const getQuarterDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('stipend_term_batch_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
quarterList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
quarterList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取季度字典失败', err)
|
||||
quarterList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类别字典
|
||||
const getClassifyDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('classify')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classifyList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
classifyList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类别字典失败', err)
|
||||
classifyList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getQuarterDict()
|
||||
getClassifyDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
378
src/views/stuwork/stipendstu/form.vue
Normal file
378
src/views/stuwork/stipendstu/form.vue
Normal file
@@ -0,0 +1,378 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="批次名称" prop="title">
|
||||
<el-input
|
||||
v-model="form.title"
|
||||
placeholder="请输入批次名称"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="form.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="form.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="季度" prop="type">
|
||||
<el-select
|
||||
v-model="form.type"
|
||||
placeholder="请选择季度"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in quarterList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="类别" prop="classify">
|
||||
<el-select
|
||||
v-model="form.classify"
|
||||
placeholder="请选择类别"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classifyList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="补助金额" prop="money">
|
||||
<el-select
|
||||
v-model="form.money"
|
||||
placeholder="请选择补助金额"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in moneyList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="开始日期" prop="startTime">
|
||||
<el-date-picker
|
||||
v-model="form.startTime"
|
||||
type="date"
|
||||
placeholder="请输入开始日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="截止日期" prop="endTime">
|
||||
<el-date-picker
|
||||
v-model="form.endTime"
|
||||
type="date"
|
||||
placeholder="请输入截止日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StipendTermBatchForm">
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { addObj, editObj, getDetail } from "/@/api/stuwork/stipendtermbatch";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
|
||||
// 定义变量内容
|
||||
const emit = defineEmits(['refresh'])
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const dataFormRef = ref()
|
||||
const operType = ref<'add' | 'edit'>('add')
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const quarterList = ref<any[]>([])
|
||||
const classifyList = ref<any[]>([])
|
||||
const moneyList = ref<any[]>([])
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
title: '',
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
type: '',
|
||||
classify: '',
|
||||
money: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
remarks: ''
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
const dataRules = reactive({
|
||||
title: [
|
||||
{ required: true, message: '请输入批次名称', trigger: 'blur' }
|
||||
],
|
||||
schoolYear: [
|
||||
{ required: true, message: '请选择学年', trigger: 'change' }
|
||||
],
|
||||
schoolTerm: [
|
||||
{ required: true, message: '请选择学期', trigger: 'change' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择季度', trigger: 'change' }
|
||||
],
|
||||
classify: [
|
||||
{ required: true, message: '请选择类别', trigger: 'change' }
|
||||
],
|
||||
money: [
|
||||
{ required: true, message: '请选择补助金额', trigger: 'change' }
|
||||
],
|
||||
startTime: [
|
||||
{ required: true, message: '请输入开始日期', trigger: 'change' }
|
||||
],
|
||||
endTime: [
|
||||
{ required: true, message: '请输入截止日期', trigger: 'change' }
|
||||
]
|
||||
})
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: 'add' | 'edit', id?: string) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
title: '',
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
type: '',
|
||||
classify: '',
|
||||
money: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
remarks: ''
|
||||
})
|
||||
|
||||
// 编辑时获取详情
|
||||
if (type === 'edit' && id) {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getDetail(id)
|
||||
if (res.data) {
|
||||
Object.assign(form, {
|
||||
id: res.data.id,
|
||||
title: res.data.title || '',
|
||||
schoolYear: res.data.schoolYear || '',
|
||||
schoolTerm: res.data.schoolTerm || '',
|
||||
type: res.data.type || '',
|
||||
classify: res.data.classify || '',
|
||||
money: res.data.money || '',
|
||||
startTime: res.data.startTime || '',
|
||||
endTime: res.data.endTime || '',
|
||||
remarks: res.data.remarks || ''
|
||||
})
|
||||
}
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '获取详情失败')
|
||||
visible.value = false
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 清除验证
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.clearValidate()
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
if (operType.value === 'add') {
|
||||
await addObj(form)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj(form)
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取季度字典
|
||||
const getQuarterDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('stipend_term_batch_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
quarterList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取季度字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类别字典
|
||||
const getClassifyDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('classify')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classifyList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类别字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取补助金额字典
|
||||
const getMoneyDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('stipendMoney')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
moneyList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取补助金额字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getQuarterDict()
|
||||
getClassifyDict()
|
||||
getMoneyDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
378
src/views/stuwork/stipendtermbatch/form.vue
Normal file
378
src/views/stuwork/stipendtermbatch/form.vue
Normal file
@@ -0,0 +1,378 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="批次名称" prop="title">
|
||||
<el-input
|
||||
v-model="form.title"
|
||||
placeholder="请输入批次名称"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="form.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="form.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="季度" prop="type">
|
||||
<el-select
|
||||
v-model="form.type"
|
||||
placeholder="请选择季度"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in quarterList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="类别" prop="classify">
|
||||
<el-select
|
||||
v-model="form.classify"
|
||||
placeholder="请选择类别"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in classifyList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="补助金额" prop="money">
|
||||
<el-select
|
||||
v-model="form.money"
|
||||
placeholder="请选择补助金额"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in moneyList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="开始日期" prop="startTime">
|
||||
<el-date-picker
|
||||
v-model="form.startTime"
|
||||
type="date"
|
||||
placeholder="请输入开始日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="截止日期" prop="endTime">
|
||||
<el-date-picker
|
||||
v-model="form.endTime"
|
||||
type="date"
|
||||
placeholder="请输入截止日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StipendTermBatchForm">
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { addObj, editObj, getDetail } from "/@/api/stuwork/stipendtermbatch";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
|
||||
// 定义变量内容
|
||||
const emit = defineEmits(['refresh'])
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const dataFormRef = ref()
|
||||
const operType = ref<'add' | 'edit'>('add')
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const quarterList = ref<any[]>([])
|
||||
const classifyList = ref<any[]>([])
|
||||
const moneyList = ref<any[]>([])
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
title: '',
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
type: '',
|
||||
classify: '',
|
||||
money: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
remarks: ''
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
const dataRules = reactive({
|
||||
title: [
|
||||
{ required: true, message: '请输入批次名称', trigger: 'blur' }
|
||||
],
|
||||
schoolYear: [
|
||||
{ required: true, message: '请选择学年', trigger: 'change' }
|
||||
],
|
||||
schoolTerm: [
|
||||
{ required: true, message: '请选择学期', trigger: 'change' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择季度', trigger: 'change' }
|
||||
],
|
||||
classify: [
|
||||
{ required: true, message: '请选择类别', trigger: 'change' }
|
||||
],
|
||||
money: [
|
||||
{ required: true, message: '请选择补助金额', trigger: 'change' }
|
||||
],
|
||||
startTime: [
|
||||
{ required: true, message: '请输入开始日期', trigger: 'change' }
|
||||
],
|
||||
endTime: [
|
||||
{ required: true, message: '请输入截止日期', trigger: 'change' }
|
||||
]
|
||||
})
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: 'add' | 'edit', id?: string) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单
|
||||
Object.assign(form, {
|
||||
id: '',
|
||||
title: '',
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
type: '',
|
||||
classify: '',
|
||||
money: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
remarks: ''
|
||||
})
|
||||
|
||||
// 编辑时获取详情
|
||||
if (type === 'edit' && id) {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getDetail(id)
|
||||
if (res.data) {
|
||||
Object.assign(form, {
|
||||
id: res.data.id,
|
||||
title: res.data.title || '',
|
||||
schoolYear: res.data.schoolYear || '',
|
||||
schoolTerm: res.data.schoolTerm || '',
|
||||
type: res.data.type || '',
|
||||
classify: res.data.classify || '',
|
||||
money: res.data.money || '',
|
||||
startTime: res.data.startTime || '',
|
||||
endTime: res.data.endTime || '',
|
||||
remarks: res.data.remarks || ''
|
||||
})
|
||||
}
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '获取详情失败')
|
||||
visible.value = false
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 清除验证
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.clearValidate()
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
if (operType.value === 'add') {
|
||||
await addObj(form)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj(form)
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取季度字典
|
||||
const getQuarterDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('stipend_term_batch_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
quarterList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取季度字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类别字典
|
||||
const getClassifyDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('classify')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classifyList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类别字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取补助金额字典
|
||||
const getMoneyDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('stipendMoney')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
moneyList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取补助金额字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getQuarterDict()
|
||||
getClassifyDict()
|
||||
getMoneyDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
322
src/views/stuwork/stipendtermbatch/index.vue
Normal file
322
src/views/stuwork/stipendtermbatch/index.vue
Normal file
@@ -0,0 +1,322 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleAdd">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="title" label="批次名称" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" label="季度" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatQuarter(scope.row.type) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="classify" label="类别" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatClassify(scope.row.classify) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="moneyValue" label="补助金额" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.moneyValue !== undefined && scope.row.moneyValue !== null ? scope.row.moneyValue : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="startTime" label="开始日期" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="endTime" label="截止日期" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remarks" label="备注" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StipendTermBatch">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/stipendtermbatch";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
const formDialogRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const quarterList = ref<any[]>([])
|
||||
const classifyList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化季度
|
||||
const formatQuarter = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = quarterList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化类别
|
||||
const formatClassify = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = classifyList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 新增
|
||||
const handleAdd = () => {
|
||||
formDialogRef.value?.openDialog('add')
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row.id)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
try {
|
||||
const { confirm } = useMessageBox()
|
||||
await confirm(`确定要删除批次 "${row.title}" 吗?`)
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取季度字典
|
||||
const getQuarterDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('stipend_term_batch_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
quarterList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
quarterList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取季度字典失败', err)
|
||||
quarterList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类别字典
|
||||
const getClassifyDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('classify')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classifyList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
classifyList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类别字典失败', err)
|
||||
classifyList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getQuarterDict()
|
||||
getClassifyDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
362
src/views/stuwork/stuassociation/form.vue
Normal file
362
src/views/stuwork/stuassociation/form.vue
Normal file
@@ -0,0 +1,362 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑社团' : '新增社团'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="社团名称" prop="associationName">
|
||||
<el-input
|
||||
v-model="form.associationName"
|
||||
placeholder="请输入社团名称"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="form.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="指导老师" prop="teacherNo">
|
||||
<el-select
|
||||
v-model="form.teacherNo"
|
||||
placeholder="请选择指导老师"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in teacherList"
|
||||
:key="item.teacherNo"
|
||||
:label="item.realName"
|
||||
:value="item.teacherNo">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="负责人" prop="maintainer">
|
||||
<el-input
|
||||
v-model="form.maintainer"
|
||||
placeholder="请输入负责人姓名"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="成立时间" prop="openTime">
|
||||
<el-date-picker
|
||||
v-model="form.openTime"
|
||||
type="date"
|
||||
placeholder="请选择成立时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="联系电话" prop="tel">
|
||||
<el-input
|
||||
v-model="form.tel"
|
||||
placeholder="请输入联系电话"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="所属类别" prop="type">
|
||||
<el-select
|
||||
v-model="form.type"
|
||||
placeholder="请选择所属类别"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="成立申请" prop="applyNote">
|
||||
<el-input
|
||||
v-model="form.applyNote"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入成立申请"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="社团章程" prop="ruleNote">
|
||||
<el-input
|
||||
v-model="form.ruleNote"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入社团章程"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuAssociationFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/stuassociation'
|
||||
import { getDeptList } from '/@/api/basic/basicclass'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
import request from '/@/utils/request'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const deptList = ref<any[]>([])
|
||||
const teacherList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
associationName: '',
|
||||
deptCode: '',
|
||||
teacherNo: '',
|
||||
maintainer: '',
|
||||
openTime: '',
|
||||
tel: '',
|
||||
type: '',
|
||||
applyNote: '',
|
||||
ruleNote: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
associationName: [
|
||||
{ required: true, message: '请输入社团名称', trigger: 'blur' }
|
||||
],
|
||||
deptCode: [
|
||||
{ required: true, message: '请选择学院', trigger: 'change' }
|
||||
],
|
||||
teacherNo: [
|
||||
{ required: true, message: '请选择指导老师', trigger: 'change' }
|
||||
],
|
||||
maintainer: [
|
||||
{ required: true, message: '请输入负责人姓名', trigger: 'blur' }
|
||||
],
|
||||
openTime: [
|
||||
{ required: true, message: '请选择成立时间', trigger: 'change' }
|
||||
],
|
||||
tel: [
|
||||
{ required: true, message: '请输入联系电话', trigger: 'blur' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择所属类别', trigger: 'change' }
|
||||
],
|
||||
applyNote: [
|
||||
{ required: true, message: '请输入成立申请', trigger: 'blur' }
|
||||
],
|
||||
ruleNote: [
|
||||
{ required: true, message: '请输入社团章程', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取教师列表
|
||||
const getTeacherList = async () => {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/professional/teacherbase/TeacherBaseList',
|
||||
method: 'get'
|
||||
})
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
teacherList.value = res.data
|
||||
} else {
|
||||
teacherList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取教师列表失败', err)
|
||||
teacherList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类别字典
|
||||
const getTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('association_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
typeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
typeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类别字典失败', err)
|
||||
typeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
operType.value = type
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.associationName = ''
|
||||
form.deptCode = ''
|
||||
form.teacherNo = ''
|
||||
form.maintainer = ''
|
||||
form.openTime = ''
|
||||
form.tel = ''
|
||||
form.type = ''
|
||||
form.applyNote = ''
|
||||
form.ruleNote = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.associationName = row.associationName || ''
|
||||
form.deptCode = row.deptCode || ''
|
||||
form.teacherNo = row.teacherNo || ''
|
||||
form.maintainer = row.maintainer || ''
|
||||
form.openTime = row.openTime || ''
|
||||
form.tel = row.tel || ''
|
||||
form.type = row.type || ''
|
||||
form.applyNote = row.applyNote || ''
|
||||
form.ruleNote = row.ruleNote || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.associationName || !row.deptCode)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.associationName = res.data.associationName || ''
|
||||
form.deptCode = res.data.deptCode || ''
|
||||
form.teacherNo = res.data.teacherNo || ''
|
||||
form.maintainer = res.data.maintainer || ''
|
||||
form.openTime = res.data.openTime || ''
|
||||
form.tel = res.data.tel || ''
|
||||
form.type = res.data.type || ''
|
||||
form.applyNote = res.data.applyNote || ''
|
||||
form.ruleNote = res.data.ruleNote || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
associationName: form.associationName,
|
||||
deptCode: form.deptCode,
|
||||
teacherNo: form.teacherNo,
|
||||
maintainer: form.maintainer,
|
||||
openTime: form.openTime,
|
||||
tel: form.tel,
|
||||
type: form.type,
|
||||
applyNote: form.applyNote,
|
||||
ruleNote: form.ruleNote
|
||||
}
|
||||
|
||||
if (operType.value === 'edit' && form.id) {
|
||||
await editObj({ ...submitData, id: form.id })
|
||||
useMessage().success('编辑成功')
|
||||
} else {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
}
|
||||
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'edit' ? '编辑失败' : '新增失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getDeptListData()
|
||||
getTeacherList()
|
||||
getTypeDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
274
src/views/stuwork/stuassociation/index.vue
Normal file
274
src/views/stuwork/stuassociation/index.vue
Normal file
@@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="指导老师姓名" prop="teacherRealName">
|
||||
<el-input
|
||||
v-model="state.queryForm.teacherRealName"
|
||||
placeholder="请输入指导老师姓名"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属类别" prop="type">
|
||||
<el-select
|
||||
v-model="state.queryForm.type"
|
||||
placeholder="请选择所属类别"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="associationName" label="社团名称" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="teacherRealName" label="指导老师姓名" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="maintainer" label="负责人" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="num" label="人数" show-overflow-tooltip align="center" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.num !== undefined && scope.row.num !== null ? scope.row.num : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="openTime" label="成立时间" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.openTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="tel" label="联系电话" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="type" label="所属类别" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ formatType(scope.row.type) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="applyNote" label="成立申请" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="ruleNote" label="社团章程" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="User"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleViewMember(scope.row)">
|
||||
查看成员
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 查看成员弹窗 -->
|
||||
<member-dialog ref="memberDialogRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuAssociation">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/stuassociation";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
import FormDialog from './form.vue'
|
||||
import MemberDialog from './member.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const memberDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const deptList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
deptCode: '',
|
||||
teacherRealName: '',
|
||||
type: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化类型
|
||||
const formatType = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = typeList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.teacherRealName = ''
|
||||
state.queryForm.type = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 查看成员
|
||||
const handleViewMember = (row: any) => {
|
||||
memberDialogRef.value?.openDialog(row.id, row.associationName)
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该社团吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类别字典
|
||||
const getTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('association_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
typeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
typeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类别字典失败', err)
|
||||
typeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getDeptListData()
|
||||
getTypeDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
134
src/views/stuwork/stuassociation/member.vue
Normal file
134
src/views/stuwork/stuassociation/member.vue
Normal file
@@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="查看成员"
|
||||
v-model="visible"
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
width="1000px">
|
||||
<div v-loading="loading">
|
||||
<div style="margin-bottom: 15px;">
|
||||
<el-text type="primary" size="large">社团名称:{{ associationName || '-' }}</el-text>
|
||||
</div>
|
||||
<el-table
|
||||
:data="memberList"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="classNo" label="班号" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="stuNo" label="学号" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="phone" label="联系电话" show-overflow-tooltip align="center" width="120" />
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-if="pagination.total > 0"
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="pagination" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuAssociationMemberDialog">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { fetchList } from '/@/api/stuwork/stuassociationmember'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
|
||||
// 定义变量内容
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const associationName = ref('')
|
||||
const associationId = ref('')
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 成员列表
|
||||
const memberList = ref<any[]>([])
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (id: string, name: string) => {
|
||||
visible.value = true
|
||||
associationId.value = id
|
||||
associationName.value = name || ''
|
||||
memberList.value = []
|
||||
pagination.current = 1
|
||||
pagination.total = 0
|
||||
|
||||
await getMemberList()
|
||||
}
|
||||
|
||||
// 获取成员列表
|
||||
const getMemberList = async () => {
|
||||
if (!associationId.value) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await fetchList({
|
||||
associationId: associationId.value,
|
||||
current: pagination.current,
|
||||
size: pagination.size
|
||||
})
|
||||
|
||||
if (res.data) {
|
||||
if (res.data.records && Array.isArray(res.data.records)) {
|
||||
memberList.value = res.data.records
|
||||
} else if (Array.isArray(res.data)) {
|
||||
memberList.value = res.data
|
||||
} else {
|
||||
memberList.value = []
|
||||
}
|
||||
|
||||
pagination.total = res.data.total || res.data.totalCount || 0
|
||||
} else {
|
||||
memberList.value = []
|
||||
pagination.total = 0
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取成员列表失败', err)
|
||||
memberList.value = []
|
||||
pagination.total = 0
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 分页变化
|
||||
const sizeChangeHandle = (size: number) => {
|
||||
pagination.size = size
|
||||
pagination.current = 1
|
||||
getMemberList()
|
||||
}
|
||||
|
||||
const currentChangeHandle = (current: number) => {
|
||||
pagination.current = current
|
||||
getMemberList()
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
302
src/views/stuwork/stucare/form.vue
Normal file
302
src/views/stuwork/stucare/form.vue
Normal file
@@ -0,0 +1,302 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="form.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
@change="handleClassChange">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学号" prop="stuNo">
|
||||
<el-select
|
||||
v-model="form.stuNo"
|
||||
:placeholder="form.classCode ? (studentLoading ? '加载中...' : '请选择学号') : '请先选择班级'"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
:disabled="!form.classCode || studentLoading"
|
||||
:loading="studentLoading"
|
||||
@change="handleStudentChange">
|
||||
<el-option
|
||||
v-for="item in studentList"
|
||||
:key="item.stuNo"
|
||||
:label="`${item.realName} (${item.stuNo})`"
|
||||
:value="item.stuNo">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="需关爱类型" prop="careType">
|
||||
<el-select
|
||||
v-model="form.careType"
|
||||
placeholder="请选择需关爱类型"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in careTypeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="危机表现" prop="present">
|
||||
<el-input
|
||||
v-model="form.present"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入危机表现"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="记录时间" prop="recordDate">
|
||||
<el-date-picker
|
||||
v-model="form.recordDate"
|
||||
type="date"
|
||||
placeholder="选择记录时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuCareFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/stucare'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import { queryAllStudentByClassCode } from '/@/api/basic/basicstudent'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const studentLoading = ref(false)
|
||||
const operType = ref('add')
|
||||
const classList = ref<any[]>([])
|
||||
const studentList = ref<any[]>([])
|
||||
const careTypeList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
classCode: '',
|
||||
stuNo: '',
|
||||
realName: '',
|
||||
careType: '',
|
||||
present: '',
|
||||
recordDate: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班级', trigger: 'change' }
|
||||
],
|
||||
stuNo: [
|
||||
{ required: true, message: '请选择学号', trigger: 'change' }
|
||||
],
|
||||
careType: [
|
||||
{ required: true, message: '请选择需关爱类型', trigger: 'change' }
|
||||
],
|
||||
present: [
|
||||
{ required: true, message: '请输入危机表现', trigger: 'blur' }
|
||||
],
|
||||
recordDate: [
|
||||
{ required: true, message: '请选择记录时间', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 班级变化
|
||||
const handleClassChange = async () => {
|
||||
form.stuNo = ''
|
||||
form.realName = ''
|
||||
studentList.value = []
|
||||
|
||||
if (form.classCode) {
|
||||
studentLoading.value = true
|
||||
try {
|
||||
const res = await queryAllStudentByClassCode(form.classCode)
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
studentList.value = res.data
|
||||
} else {
|
||||
studentList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学生列表失败', err)
|
||||
useMessage().error('获取学生列表失败')
|
||||
studentList.value = []
|
||||
} finally {
|
||||
studentLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 学生变化
|
||||
const handleStudentChange = () => {
|
||||
const student = studentList.value.find(item => item.stuNo === form.stuNo)
|
||||
if (student) {
|
||||
form.realName = student.realName || ''
|
||||
} else {
|
||||
form.realName = ''
|
||||
}
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.classCode = ''
|
||||
form.stuNo = ''
|
||||
form.realName = ''
|
||||
form.careType = ''
|
||||
form.present = ''
|
||||
form.recordDate = ''
|
||||
studentList.value = []
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.classCode = row.classCode || ''
|
||||
form.stuNo = row.stuNo || ''
|
||||
form.realName = row.realName || ''
|
||||
form.careType = row.careType || ''
|
||||
form.present = row.present || ''
|
||||
form.recordDate = row.recordDate || ''
|
||||
|
||||
// 加载学生列表
|
||||
if (form.classCode) {
|
||||
handleClassChange()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
classCode: form.classCode,
|
||||
stuNo: form.stuNo,
|
||||
careType: form.careType,
|
||||
present: form.present,
|
||||
recordDate: form.recordDate
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取需关爱类型字典
|
||||
const getCareTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('stu_care_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
careTypeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取需关爱类型字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getClassListData()
|
||||
getCareTypeDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
378
src/views/stuwork/stucare/index.vue
Normal file
378
src/views/stuwork/stucare/index.vue
Normal file
@@ -0,0 +1,378 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="state.queryForm.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学号" prop="stuNo">
|
||||
<el-input
|
||||
v-model="state.queryForm.stuNo"
|
||||
placeholder="请输入学号"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="classNo" label="班级" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="teacherRealName" label="班主任姓名" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="teacherTel" label="班主任电话" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="careType" label="需关爱类型" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatCareType(scope.row.careType) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="present" label="危机表现" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="recordDate" label="记录时间" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.recordDate || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="result" label="干预结果" show-overflow-tooltip align="center" min-width="150">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.result || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Document"
|
||||
text
|
||||
type="success"
|
||||
@click="handleResult(scope.row)">
|
||||
干预结果
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 干预结果弹窗 -->
|
||||
<result-dialog ref="resultDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuCare">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/stucare";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import FormDialog from './form.vue'
|
||||
import ResultDialog from './result.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const resultDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const careTypeList = ref<any[]>([])
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
deptCode: '',
|
||||
classCode: '',
|
||||
realName: '',
|
||||
stuNo: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化需关爱类型
|
||||
const formatCareType = (value: string) => {
|
||||
if (!value) return '-'
|
||||
const item = careTypeList.value.find((item: any) => item.value === value)
|
||||
return item ? item.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.classCode = ''
|
||||
state.queryForm.realName = ''
|
||||
state.queryForm.stuNo = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 干预结果
|
||||
const handleResult = (row: any) => {
|
||||
resultDialogRef.value?.openDialog(row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该心理健康记录吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取需关爱类型字典
|
||||
const getCareTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('stu_care_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
careTypeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
careTypeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取需关爱类型字典失败', err)
|
||||
careTypeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
getCareTypeDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
151
src/views/stuwork/stucare/result.vue
Normal file
151
src/views/stuwork/stucare/result.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="干预结果"
|
||||
v-model="visible"
|
||||
:width="600"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="学生姓名">
|
||||
<el-input v-model="form.realName" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="学号">
|
||||
<el-input v-model="form.stuNo" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="班级">
|
||||
<el-input v-model="form.classNo" disabled style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="干预结果" prop="result">
|
||||
<el-input
|
||||
v-model="form.result"
|
||||
type="textarea"
|
||||
:rows="6"
|
||||
placeholder="请输入干预结果"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuCareResultDialog">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { updateResult, getDetail } from '/@/api/stuwork/stucare'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
realName: '',
|
||||
stuNo: '',
|
||||
classNo: '',
|
||||
result: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
result: [
|
||||
{ required: true, message: '请输入干预结果', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.realName = ''
|
||||
form.stuNo = ''
|
||||
form.classNo = ''
|
||||
form.result = ''
|
||||
|
||||
if (row) {
|
||||
form.id = row.id
|
||||
form.realName = row.realName || ''
|
||||
form.stuNo = row.stuNo || ''
|
||||
form.classNo = row.classNo || ''
|
||||
form.result = row.result || ''
|
||||
|
||||
// 如果没有干预结果,尝试获取详情
|
||||
if (row.id && !row.result) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.result = res.data.result || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
await updateResult({
|
||||
id: form.id,
|
||||
result: form.result
|
||||
})
|
||||
useMessage().success('保存成功')
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '保存失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
406
src/views/stuwork/stuconduct/form.vue
Normal file
406
src/views/stuwork/stuconduct/form.vue
Normal file
@@ -0,0 +1,406 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑' : '新增'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="form.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
:disabled="!!form.id">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="form.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
:disabled="!!form.id">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="form.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
@change="handleClassChange">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学生" prop="stuNo">
|
||||
<el-select
|
||||
v-model="form.stuNo"
|
||||
:placeholder="form.classCode ? '请选择学生' : '请先选择班级'"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
:disabled="!form.classCode || studentLoading"
|
||||
:loading="studentLoading"
|
||||
@change="handleStudentChange">
|
||||
<el-option
|
||||
v-for="item in studentList"
|
||||
:key="item.stuNo"
|
||||
:label="`${item.realName} (${item.stuNo})`"
|
||||
:value="item.stuNo">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="分数" prop="score">
|
||||
<el-input-number
|
||||
v-model="form.score"
|
||||
:min="0"
|
||||
:max="100"
|
||||
placeholder="请输入分数"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="类型" prop="conductType">
|
||||
<el-select
|
||||
v-model="form.conductType"
|
||||
placeholder="请选择类型"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="考核时间" prop="recordDate">
|
||||
<el-date-picker
|
||||
v-model="form.recordDate"
|
||||
type="date"
|
||||
placeholder="选择考核时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="情况记录" prop="description">
|
||||
<el-input
|
||||
v-model="form.description"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入情况记录"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="附件" prop="attachment">
|
||||
<upload-file
|
||||
v-model="form.attachment"
|
||||
:limit="5"
|
||||
:fileSize="10"
|
||||
type="simple" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuConductFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/stuconduct'
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear'
|
||||
import { queryAllStudentByClassCode } from '/@/api/basic/basicstudent'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
import UploadFile from '/@/components/Upload/index.vue'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const studentLoading = ref(false)
|
||||
const operType = ref('add')
|
||||
const classList = ref<any[]>([])
|
||||
const studentList = ref<any[]>([])
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
classCode: '',
|
||||
stuNo: '',
|
||||
score: 0,
|
||||
conductType: '',
|
||||
recordDate: '',
|
||||
description: '',
|
||||
attachment: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
schoolYear: [
|
||||
{ required: true, message: '请选择学年', trigger: 'change' }
|
||||
],
|
||||
schoolTerm: [
|
||||
{ required: true, message: '请选择学期', trigger: 'change' }
|
||||
],
|
||||
classCode: [
|
||||
{ required: true, message: '请选择班级', trigger: 'change' }
|
||||
],
|
||||
stuNo: [
|
||||
{ required: true, message: '请选择学生', trigger: 'change' }
|
||||
],
|
||||
score: [
|
||||
{ required: true, message: '请输入分数', trigger: 'blur' }
|
||||
],
|
||||
conductType: [
|
||||
{ required: true, message: '请选择类型', trigger: 'change' }
|
||||
],
|
||||
recordDate: [
|
||||
{ required: true, message: '请选择考核时间', trigger: 'change' }
|
||||
],
|
||||
description: [
|
||||
{ required: true, message: '请输入情况记录', trigger: 'blur' }
|
||||
]
|
||||
// attachment 非必填,不需要验证规则
|
||||
}
|
||||
|
||||
// 班级变化
|
||||
const handleClassChange = async () => {
|
||||
form.stuNo = ''
|
||||
studentList.value = []
|
||||
|
||||
if (form.classCode) {
|
||||
studentLoading.value = true
|
||||
try {
|
||||
const res = await queryAllStudentByClassCode(form.classCode)
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
studentList.value = res.data
|
||||
} else {
|
||||
studentList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学生列表失败', err)
|
||||
useMessage().error('获取学生列表失败')
|
||||
studentList.value = []
|
||||
} finally {
|
||||
studentLoading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 学生变化
|
||||
const handleStudentChange = () => {
|
||||
// 学生选择后可以做一些处理,这里暂时不需要
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
visible.value = true
|
||||
operType.value = type
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.schoolYear = ''
|
||||
form.schoolTerm = ''
|
||||
form.classCode = ''
|
||||
form.stuNo = ''
|
||||
form.score = 0
|
||||
form.conductType = ''
|
||||
form.recordDate = ''
|
||||
form.description = ''
|
||||
form.attachment = ''
|
||||
studentList.value = []
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.schoolYear = row.schoolYear || ''
|
||||
form.schoolTerm = row.schoolTerm || ''
|
||||
form.classCode = row.classCode || ''
|
||||
form.stuNo = row.stuNo || ''
|
||||
form.score = row.score || 0
|
||||
form.conductType = row.conductType || ''
|
||||
form.recordDate = row.recordDate || ''
|
||||
form.description = row.description || ''
|
||||
form.attachment = row.attachment || ''
|
||||
|
||||
// 加载学生列表
|
||||
if (form.classCode) {
|
||||
handleClassChange()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
schoolYear: form.schoolYear,
|
||||
schoolTerm: form.schoolTerm,
|
||||
classCode: form.classCode,
|
||||
stuNo: form.stuNo,
|
||||
score: form.score,
|
||||
conductType: form.conductType,
|
||||
recordDate: form.recordDate,
|
||||
description: form.description,
|
||||
attachment: form.attachment || ''
|
||||
}
|
||||
|
||||
if (operType.value === 'add') {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
} else {
|
||||
await editObj({
|
||||
id: form.id,
|
||||
...submitData
|
||||
})
|
||||
useMessage().success('编辑成功')
|
||||
}
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类型字典
|
||||
const getTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('conduct_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
typeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类型字典失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getClassListData()
|
||||
getTypeDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
472
src/views/stuwork/stuconduct/index.vue
Normal file
472
src/views/stuwork/stuconduct/index.vue
Normal file
@@ -0,0 +1,472 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px"
|
||||
@change="handleDeptChange">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="state.queryForm.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="conductType">
|
||||
<el-select
|
||||
v-model="state.queryForm.conductType"
|
||||
placeholder="请选择类型"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Upload"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleImport">
|
||||
导入
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="stuNo" label="学号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="classNo" label="班级" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="conductType" label="类型" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ formatType(scope.row.conductType) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="recordDate" label="考核时间" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.recordDate || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="description" label="情况记录" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="attachment" label="附件" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.attachment"
|
||||
icon="Document"
|
||||
text
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleViewAttachment(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 导入弹窗 -->
|
||||
<el-dialog
|
||||
title="导入操行考核"
|
||||
v-model="importDialogVisible"
|
||||
:width="500"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:auto-upload="false"
|
||||
:on-change="handleFileChange"
|
||||
:limit="1"
|
||||
accept=".xlsx,.xls"
|
||||
drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
只能上传 xlsx/xls 文件
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="importDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :disabled="!importFile || importLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuConduct">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, importExcel } from "/@/api/stuwork/stuconduct";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { UploadFilled } from '@element-plus/icons-vue'
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const uploadRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([])
|
||||
const importDialogVisible = ref(false)
|
||||
const importFile = ref<File | null>(null)
|
||||
const importLoading = ref(false)
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
deptCode: '',
|
||||
classCode: '',
|
||||
realName: '',
|
||||
conductType: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化类型
|
||||
const formatType = (value: string) => {
|
||||
if (!value) return '-'
|
||||
const item = typeList.value.find((item: any) => item.value === value)
|
||||
return item ? item.label : value
|
||||
}
|
||||
|
||||
// 学院变化
|
||||
const handleDeptChange = () => {
|
||||
// 可以根据学院筛选班级,这里暂时不实现
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.classCode = ''
|
||||
state.queryForm.realName = ''
|
||||
state.queryForm.conductType = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 查看附件
|
||||
const handleViewAttachment = (row: any) => {
|
||||
if (row.attachment) {
|
||||
const urls = typeof row.attachment === 'string' ? row.attachment.split(',') : [row.attachment]
|
||||
urls.forEach((url: string) => {
|
||||
if (url.trim()) {
|
||||
window.open(url.trim(), '_blank')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 导入
|
||||
const handleImport = () => {
|
||||
importDialogVisible.value = true
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
}
|
||||
|
||||
// 文件变化
|
||||
const handleFileChange = (file: any) => {
|
||||
importFile.value = file.raw
|
||||
}
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (!importFile.value) {
|
||||
useMessage().warning('请选择要导入的文件')
|
||||
return
|
||||
}
|
||||
|
||||
importLoading.value = true
|
||||
try {
|
||||
await importExcel(importFile.value)
|
||||
useMessage().success('导入成功')
|
||||
importDialogVisible.value = false
|
||||
importFile.value = null
|
||||
uploadRef.value?.clearFiles()
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败')
|
||||
} finally {
|
||||
importLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该操行考核记录吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类型字典
|
||||
const getTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('conduct_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
typeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
typeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类型字典失败', err)
|
||||
typeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
getTypeDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
372
src/views/stuwork/stuconduct/indexTerm.vue
Normal file
372
src/views/stuwork/stuconduct/indexTerm.vue
Normal file
@@ -0,0 +1,372 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 统计表格 -->
|
||||
<el-row style="margin-bottom: 20px;">
|
||||
<el-table
|
||||
:data="statisticsData"
|
||||
v-loading="loading"
|
||||
border
|
||||
style="width: 100%"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column prop="label" label="" width="120" align="center" fixed="left" />
|
||||
<el-table-column prop="classNo" label="班级" min-width="150" align="center" />
|
||||
<el-table-column prop="excellent" label="优秀" min-width="100" align="center" />
|
||||
<el-table-column prop="good" label="良好" min-width="100" align="center" />
|
||||
<el-table-column prop="pass" label="及格" min-width="100" align="center" />
|
||||
<el-table-column prop="fail" label="不及格" min-width="100" align="center" />
|
||||
</el-table>
|
||||
</el-row>
|
||||
|
||||
<!-- 学生列表表格 -->
|
||||
<el-row>
|
||||
<el-table
|
||||
:data="studentList"
|
||||
v-loading="loading"
|
||||
border
|
||||
:max-height="600"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="stuNo" label="学号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="score" label="学期总评" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.score !== null && scope.row.score !== undefined ? scope.row.score.toFixed(2) : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleView(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuConductTerm">
|
||||
import { reactive, ref, onMounted, computed } from 'vue'
|
||||
import { getStuConductTerm } from "/@/api/stuwork/stuconduct";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
|
||||
// 表格样式 - 在组件内部定义,不从外部导入
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const loading = ref(false)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const studentList = ref<any[]>([])
|
||||
|
||||
// 查询表单
|
||||
const queryForm = reactive({
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
classCode: ''
|
||||
})
|
||||
|
||||
// 统计表格数据
|
||||
const statisticsData = computed(() => {
|
||||
if (studentList.value.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
// 计算各等级人数
|
||||
// 优秀:>=90,良好:80-89,及格:60-79,不及格:<60
|
||||
let excellent = 0 // 优秀
|
||||
let good = 0 // 良好
|
||||
let pass = 0 // 及格
|
||||
let fail = 0 // 不及格
|
||||
const total = studentList.value.length
|
||||
|
||||
studentList.value.forEach((student: any) => {
|
||||
const score = student.score
|
||||
if (score !== null && score !== undefined) {
|
||||
if (score >= 90) {
|
||||
excellent++
|
||||
} else if (score >= 80) {
|
||||
good++
|
||||
} else if (score >= 60) {
|
||||
pass++
|
||||
} else {
|
||||
fail++
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 计算比率
|
||||
const excellentRate = total > 0 ? ((excellent / total) * 100).toFixed(2) + '%' : '0%'
|
||||
const goodRate = total > 0 ? ((good / total) * 100).toFixed(2) + '%' : '0%'
|
||||
const passRate = total > 0 ? ((pass / total) * 100).toFixed(2) + '%' : '0%'
|
||||
const failRate = total > 0 ? ((fail / total) * 100).toFixed(2) + '%' : '0%'
|
||||
|
||||
// 优良率 = (优秀 + 良好) / 总人数
|
||||
const excellentGoodCount = excellent + good
|
||||
const excellentGoodRate = total > 0 ? ((excellentGoodCount / total) * 100).toFixed(2) + '%' : '0%'
|
||||
|
||||
// 获取班级名称
|
||||
const classNo = studentList.value.length > 0 ? (studentList.value[0].classNo || '-') : '-'
|
||||
|
||||
return [
|
||||
{
|
||||
label: '人数',
|
||||
classNo: classNo,
|
||||
excellent: excellent,
|
||||
good: good,
|
||||
pass: pass,
|
||||
fail: fail
|
||||
},
|
||||
{
|
||||
label: '比率',
|
||||
classNo: classNo,
|
||||
excellent: excellentRate,
|
||||
good: goodRate,
|
||||
pass: passRate,
|
||||
fail: failRate
|
||||
},
|
||||
{
|
||||
label: '优良率',
|
||||
classNo: classNo,
|
||||
excellent: excellentGoodRate,
|
||||
good: '-',
|
||||
pass: '-',
|
||||
fail: '-'
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
classNo: classNo,
|
||||
excellent: '-',
|
||||
good: '-',
|
||||
pass: '-',
|
||||
fail: '-'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 获取数据列表
|
||||
const getDataList = async () => {
|
||||
if (!queryForm.schoolYear || !queryForm.schoolTerm || !queryForm.classCode) {
|
||||
useMessage().warning('请选择学年、学期和班级')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getStuConductTerm({
|
||||
schoolYear: queryForm.schoolYear,
|
||||
schoolTerm: queryForm.schoolTerm,
|
||||
classCode: queryForm.classCode
|
||||
})
|
||||
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
// 处理返回的数据,提取学生列表
|
||||
// 根据API文档,返回的是StuConductTermVO数组
|
||||
const tempList: any[] = []
|
||||
|
||||
res.data.forEach((item: any) => {
|
||||
// 如果返回的数据结构中有basicStudentVOList,需要展开
|
||||
if (item.basicStudentVOList && Array.isArray(item.basicStudentVOList) && item.basicStudentVOList.length > 0) {
|
||||
item.basicStudentVOList.forEach((student: any) => {
|
||||
tempList.push({
|
||||
stuNo: student.stuNo || item.stuNo,
|
||||
realName: student.realName || item.realName,
|
||||
score: item.score, // 学期总评分数
|
||||
classNo: item.classNo,
|
||||
classCode: item.classCode
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// 直接使用item作为学生信息
|
||||
tempList.push({
|
||||
stuNo: item.stuNo,
|
||||
realName: item.realName,
|
||||
score: item.score,
|
||||
classNo: item.classNo,
|
||||
classCode: item.classCode
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
studentList.value = tempList
|
||||
} else {
|
||||
studentList.value = []
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('获取数据列表失败', err)
|
||||
useMessage().error(err.msg || '获取数据列表失败')
|
||||
studentList.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
queryForm.schoolYear = ''
|
||||
queryForm.schoolTerm = ''
|
||||
queryForm.classCode = ''
|
||||
studentList.value = []
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const handleView = (row: any) => {
|
||||
// 可以跳转到详情页面或打开详情弹窗
|
||||
useMessage().info('查看详情功能待实现')
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getClassListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.layout-padding {
|
||||
.layout-padding-auto {
|
||||
.layout-padding-view {
|
||||
.el-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 确保页面可以滚动
|
||||
.layout-padding {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
.layout-padding-auto {
|
||||
height: 100%;
|
||||
|
||||
.layout-padding-view {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
334
src/views/stuwork/stuconduct/indexYear.vue
Normal file
334
src/views/stuwork/stuconduct/indexYear.vue
Normal file
@@ -0,0 +1,334 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 统计表格 -->
|
||||
<el-row style="margin-bottom: 20px;">
|
||||
<el-table
|
||||
:data="statisticsData"
|
||||
v-loading="loading"
|
||||
border
|
||||
style="width: 100%"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column prop="label" label="" width="120" align="center" fixed="left" />
|
||||
<el-table-column prop="classNo" label="班级" min-width="150" align="center" />
|
||||
<el-table-column prop="excellent" label="优秀" min-width="100" align="center" />
|
||||
<el-table-column prop="good" label="良好" min-width="100" align="center" />
|
||||
<el-table-column prop="pass" label="及格" min-width="100" align="center" />
|
||||
<el-table-column prop="fail" label="不及格" min-width="100" align="center" />
|
||||
</el-table>
|
||||
</el-row>
|
||||
|
||||
<!-- 学生列表表格 -->
|
||||
<el-row>
|
||||
<el-table
|
||||
:data="studentList"
|
||||
v-loading="loading"
|
||||
border
|
||||
:max-height="600"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="stuNo" label="学号" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="score" label="学年总评" show-overflow-tooltip align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.score !== null && scope.row.score !== undefined ? scope.row.score.toFixed(2) : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleView(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuConductYear">
|
||||
import { reactive, ref, onMounted, computed } from 'vue'
|
||||
import { getStuConductYear } from "/@/api/stuwork/stuconduct";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
|
||||
// 表格样式 - 在组件内部定义,不从外部导入
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const loading = ref(false)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const studentList = ref<any[]>([])
|
||||
|
||||
// 查询表单
|
||||
const queryForm = reactive({
|
||||
schoolYear: '',
|
||||
classCode: ''
|
||||
})
|
||||
|
||||
// 统计表格数据
|
||||
const statisticsData = computed(() => {
|
||||
if (studentList.value.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
// 计算各等级人数
|
||||
// 优秀:>=90,良好:80-89,及格:60-79,不及格:<60
|
||||
let excellent = 0 // 优秀
|
||||
let good = 0 // 良好
|
||||
let pass = 0 // 及格
|
||||
let fail = 0 // 不及格
|
||||
const total = studentList.value.length
|
||||
|
||||
studentList.value.forEach((student: any) => {
|
||||
const score = student.score
|
||||
if (score !== null && score !== undefined) {
|
||||
if (score >= 90) {
|
||||
excellent++
|
||||
} else if (score >= 80) {
|
||||
good++
|
||||
} else if (score >= 60) {
|
||||
pass++
|
||||
} else {
|
||||
fail++
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 计算比率
|
||||
const excellentRate = total > 0 ? ((excellent / total) * 100).toFixed(2) + '%' : '0%'
|
||||
const goodRate = total > 0 ? ((good / total) * 100).toFixed(2) + '%' : '0%'
|
||||
const passRate = total > 0 ? ((pass / total) * 100).toFixed(2) + '%' : '0%'
|
||||
const failRate = total > 0 ? ((fail / total) * 100).toFixed(2) + '%' : '0%'
|
||||
|
||||
// 优良率 = (优秀 + 良好) / 总人数
|
||||
const excellentGoodCount = excellent + good
|
||||
const excellentGoodRate = total > 0 ? ((excellentGoodCount / total) * 100).toFixed(2) + '%' : '0%'
|
||||
|
||||
// 获取班级名称
|
||||
const classNo = studentList.value.length > 0 ? (studentList.value[0].classNo || '-') : '-'
|
||||
|
||||
return [
|
||||
{
|
||||
label: '人数',
|
||||
classNo: classNo,
|
||||
excellent: excellent,
|
||||
good: good,
|
||||
pass: pass,
|
||||
fail: fail
|
||||
},
|
||||
{
|
||||
label: '比率',
|
||||
classNo: classNo,
|
||||
excellent: excellentRate,
|
||||
good: goodRate,
|
||||
pass: passRate,
|
||||
fail: failRate
|
||||
},
|
||||
{
|
||||
label: '优良率',
|
||||
classNo: classNo,
|
||||
excellent: excellentGoodRate,
|
||||
good: '-',
|
||||
pass: '-',
|
||||
fail: '-'
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
classNo: classNo,
|
||||
excellent: '-',
|
||||
good: '-',
|
||||
pass: '-',
|
||||
fail: '-'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 获取数据列表
|
||||
const getDataList = async () => {
|
||||
if (!queryForm.schoolYear || !queryForm.classCode) {
|
||||
useMessage().warning('请选择学年和班级')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getStuConductYear({
|
||||
schoolYear: queryForm.schoolYear,
|
||||
classCode: queryForm.classCode
|
||||
})
|
||||
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
// 处理返回的数据,提取学生列表
|
||||
// 根据API文档,返回的是StuConductYearVO数组
|
||||
const tempList: any[] = []
|
||||
|
||||
res.data.forEach((item: any) => {
|
||||
// 如果返回的数据结构中有basicStudentVOList,需要展开
|
||||
if (item.basicStudentVOList && Array.isArray(item.basicStudentVOList) && item.basicStudentVOList.length > 0) {
|
||||
item.basicStudentVOList.forEach((student: any) => {
|
||||
tempList.push({
|
||||
stuNo: student.stuNo || item.stuNo,
|
||||
realName: student.realName || item.realName,
|
||||
score: item.score, // 学年总评分数
|
||||
classNo: item.classNo,
|
||||
classCode: item.classCode
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// 直接使用item作为学生信息
|
||||
tempList.push({
|
||||
stuNo: item.stuNo,
|
||||
realName: item.realName,
|
||||
score: item.score,
|
||||
classNo: item.classNo,
|
||||
classCode: item.classCode
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
studentList.value = tempList
|
||||
} else {
|
||||
studentList.value = []
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('获取数据列表失败', err)
|
||||
useMessage().error(err.msg || '获取数据列表失败')
|
||||
studentList.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
queryForm.schoolYear = ''
|
||||
queryForm.classCode = ''
|
||||
studentList.value = []
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const handleView = (row: any) => {
|
||||
// 可以跳转到详情页面或打开详情弹窗
|
||||
useMessage().info('查看详情功能待实现')
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getClassListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.layout-padding {
|
||||
.layout-padding-auto {
|
||||
.layout-padding-view {
|
||||
.el-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 确保页面可以滚动
|
||||
.layout-padding {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
|
||||
.layout-padding-auto {
|
||||
height: 100%;
|
||||
|
||||
.layout-padding-view {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
216
src/views/stuwork/stuunion/form.vue
Normal file
216
src/views/stuwork/stuunion/form.vue
Normal file
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="编辑学生会"
|
||||
v-model="visible"
|
||||
:width="700"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="学生会名称" prop="unionName">
|
||||
<el-input
|
||||
v-model="form.unionName"
|
||||
placeholder="学生会名称"
|
||||
disabled
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="类型" prop="unionType">
|
||||
<el-select
|
||||
v-model="form.unionType"
|
||||
placeholder="类型"
|
||||
disabled
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in unionTypeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="联系地址" prop="address">
|
||||
<el-input
|
||||
v-model="form.address"
|
||||
placeholder="请输入联系地址"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="负责人" prop="maintainer">
|
||||
<el-input
|
||||
v-model="form.maintainer"
|
||||
placeholder="请输入负责人"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number
|
||||
v-model="form.sort"
|
||||
:min="0"
|
||||
placeholder="请输入排序"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuUnionFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { editObj, getDetail } from '/@/api/stuwork/stuunion'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const unionTypeList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
unionName: '',
|
||||
unionType: '',
|
||||
address: '',
|
||||
maintainer: '',
|
||||
sort: undefined as number | undefined
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
address: [
|
||||
{ required: true, message: '请输入联系地址', trigger: 'blur' }
|
||||
],
|
||||
maintainer: [
|
||||
{ required: true, message: '请输入负责人', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 获取类型字典
|
||||
const getUnionTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('union_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
unionTypeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
unionTypeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类型字典失败', err)
|
||||
unionTypeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'edit', row?: any) => {
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.unionName = ''
|
||||
form.unionType = ''
|
||||
form.address = ''
|
||||
form.maintainer = ''
|
||||
form.sort = undefined
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.unionName = row.unionName || ''
|
||||
form.unionType = row.unionType || ''
|
||||
form.address = row.address || ''
|
||||
form.maintainer = row.maintainer || ''
|
||||
form.sort = row.sort !== undefined && row.sort !== null ? row.sort : undefined
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.address || !row.maintainer)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.unionName = res.data.unionName || ''
|
||||
form.unionType = res.data.unionType || ''
|
||||
form.address = res.data.address || ''
|
||||
form.maintainer = res.data.maintainer || ''
|
||||
form.sort = res.data.sort !== undefined && res.data.sort !== null ? res.data.sort : undefined
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
id: form.id,
|
||||
address: form.address,
|
||||
maintainer: form.maintainer,
|
||||
sort: form.sort !== undefined && form.sort !== null ? form.sort : undefined
|
||||
}
|
||||
|
||||
await editObj(submitData)
|
||||
useMessage().success('编辑成功')
|
||||
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '编辑失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getUnionTypeDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
140
src/views/stuwork/stuunion/index.vue
Normal file
140
src/views/stuwork/stuunion/index.vue
Normal file
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="unionName" label="学生会名称" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="unionType" label="类型" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ formatUnionType(scope.row.unionType) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="address" label="联系地址" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="maintainer" label="负责人" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="sort" label="排序" show-overflow-tooltip align="center" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.sort !== undefined && scope.row.sort !== null ? scope.row.sort : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuUnion">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList } from "/@/api/stuwork/stuunion";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const showSearch = ref(false)
|
||||
const unionTypeList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true // 页面加载时自动获取数据
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化类型
|
||||
const formatUnionType = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = unionTypeList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 获取类型字典
|
||||
const getUnionTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('union_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
unionTypeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
unionTypeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类型字典失败', err)
|
||||
unionTypeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getUnionTypeDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
183
src/views/stuwork/stuunionleague/form.vue
Normal file
183
src/views/stuwork/stuunionleague/form.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑团员' : '新增团员'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学号" prop="stuNo">
|
||||
<el-input
|
||||
v-model="form.stuNo"
|
||||
placeholder="请输入学号"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="入团时间" prop="enterTime">
|
||||
<el-date-picker
|
||||
v-model="form.enterTime"
|
||||
type="date"
|
||||
placeholder="请输入入团时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="团员编号" prop="serNo">
|
||||
<el-input
|
||||
v-model="form.serNo"
|
||||
placeholder="请输入团员编号"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="团内职务" prop="position">
|
||||
<el-input
|
||||
v-model="form.position"
|
||||
placeholder="请输入团内职务"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuUnionLeagueFormDialog">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/stuunionleague'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
stuNo: '',
|
||||
enterTime: '',
|
||||
serNo: '',
|
||||
position: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
stuNo: [
|
||||
{ required: true, message: '请输入学号', trigger: 'blur' }
|
||||
],
|
||||
enterTime: [
|
||||
{ required: true, message: '请输入入团时间', trigger: 'change' }
|
||||
],
|
||||
serNo: [
|
||||
{ required: true, message: '请输入团员编号', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
operType.value = type
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.stuNo = ''
|
||||
form.enterTime = ''
|
||||
form.serNo = ''
|
||||
form.position = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.stuNo = row.stuNo || ''
|
||||
form.enterTime = row.enterTime || ''
|
||||
form.serNo = row.serNo || ''
|
||||
form.position = row.position || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.stuNo || !row.enterTime)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.stuNo = res.data.stuNo || ''
|
||||
form.enterTime = res.data.enterTime || ''
|
||||
form.serNo = res.data.serNo || ''
|
||||
form.position = res.data.position || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
stuNo: form.stuNo,
|
||||
enterTime: form.enterTime,
|
||||
serNo: form.serNo,
|
||||
position: form.position
|
||||
}
|
||||
|
||||
if (operType.value === 'edit' && form.id) {
|
||||
await editObj({ ...submitData, id: form.id })
|
||||
useMessage().success('编辑成功')
|
||||
} else {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
}
|
||||
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'edit' ? '编辑失败' : '新增失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
368
src/views/stuwork/stuunionleague/index.vue
Normal file
368
src/views/stuwork/stuunionleague/index.vue
Normal file
@@ -0,0 +1,368 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班号" prop="classNo">
|
||||
<el-input
|
||||
v-model="state.queryForm.classNo"
|
||||
placeholder="请输入班号"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="realName">
|
||||
<el-input
|
||||
v-model="state.queryForm.realName"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="团员编号" prop="serNo">
|
||||
<el-input
|
||||
v-model="state.queryForm.serNo"
|
||||
placeholder="请输入团员编号"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="入学年份" prop="grade">
|
||||
<el-select
|
||||
v-model="state.queryForm.grade"
|
||||
placeholder="请选择入学年份"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in gradeList"
|
||||
:key="item.grade"
|
||||
:label="item.grade"
|
||||
:value="item.grade">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Upload"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleImport">
|
||||
导入
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleExport">
|
||||
导出
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="classNo" label="班级" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="stuNo" label="学号" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="phone" label="联系电话" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="enterTime" label="入团时间" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.enterTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="serNo" label="团员编号" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="position" label="团内职务" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 导入弹窗 -->
|
||||
<el-dialog
|
||||
title="导入团员"
|
||||
v-model="importDialogVisible"
|
||||
:close-on-click-modal="false"
|
||||
width="500px">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
:auto-upload="false"
|
||||
:limit="1"
|
||||
:on-exceed="handleExceed"
|
||||
:on-change="handleFileChange"
|
||||
:file-list="fileList"
|
||||
accept=".xlsx,.xls"
|
||||
drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">
|
||||
只能上传 xlsx/xls 文件
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="importDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :loading="importLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuUnionLeague">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, importExcel, exportExcel } from "/@/api/stuwork/stuunionleague";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getGradeList } from "/@/api/basic/basicclass";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
import { UploadFilled } from '@element-plus/icons-vue';
|
||||
import type { UploadFile, UploadFiles } from 'element-plus';
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const uploadRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const classList = ref<any[]>([])
|
||||
const gradeList = ref<any[]>([])
|
||||
const importDialogVisible = ref(false)
|
||||
const importLoading = ref(false)
|
||||
const fileList = ref<UploadFile[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
classCode: '',
|
||||
classNo: '',
|
||||
realName: '',
|
||||
serNo: '',
|
||||
grade: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.classCode = ''
|
||||
state.queryForm.classNo = ''
|
||||
state.queryForm.realName = ''
|
||||
state.queryForm.serNo = ''
|
||||
state.queryForm.grade = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该团员吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导入
|
||||
const handleImport = () => {
|
||||
importDialogVisible.value = true
|
||||
fileList.value = []
|
||||
}
|
||||
|
||||
// 文件变化
|
||||
const handleFileChange = (file: UploadFile, files: UploadFiles) => {
|
||||
fileList.value = [file]
|
||||
}
|
||||
|
||||
// 文件超出限制
|
||||
const handleExceed = () => {
|
||||
useMessage().warning('只能上传一个文件')
|
||||
}
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (fileList.value.length === 0) {
|
||||
useMessage().warning('请选择要上传的文件')
|
||||
return
|
||||
}
|
||||
|
||||
const file = fileList.value[0].raw
|
||||
if (!file) {
|
||||
useMessage().warning('文件不存在')
|
||||
return
|
||||
}
|
||||
|
||||
importLoading.value = true
|
||||
try {
|
||||
await importExcel(file as File)
|
||||
useMessage().success('导入成功')
|
||||
importDialogVisible.value = false
|
||||
fileList.value = []
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败')
|
||||
} finally {
|
||||
importLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const res = await exportExcel(state.queryForm)
|
||||
const blob = new Blob([res.data as BlobPart])
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = `团员列表_${parseTime(new Date(), '{y}{m}{d}{h}{i}{s}')}.xlsx`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
useMessage().success('导出成功')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取入学年份列表
|
||||
const getGradeListData = async () => {
|
||||
try {
|
||||
const res = await getGradeList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
gradeList.value = res.data
|
||||
} else {
|
||||
gradeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取入学年份列表失败', err)
|
||||
gradeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getClassListData()
|
||||
getGradeListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
371
src/views/stuwork/tuitionfreestu/apply.vue
Normal file
371
src/views/stuwork/tuitionfreestu/apply.vue
Normal file
@@ -0,0 +1,371 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Document"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
:disabled="selectedRows.length === 0"
|
||||
@click="handleApply">
|
||||
申请免学费
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="classNo" label="班级" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="majorName" label="专业" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="stuNo" label="学号" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="gender" label="性别" show-overflow-tooltip align="center" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ formatGender(scope.row.gender) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="idCard" label="身份证号" show-overflow-tooltip align="center" min-width="180" />
|
||||
<el-table-column prop="bankCard" label="中职卡号" show-overflow-tooltip align="center" width="150" />
|
||||
<el-table-column prop="phone" label="联系方式" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="education" label="生源" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatEducation(scope.row.education) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="majorLevel" label="层次" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatMajorLevel(scope.row.majorLevel) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="grade" label="入学年份" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="gradeCurr" label="当前年纪" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="temporaryyeYear" label="借读学年" show-overflow-tooltip align="center" width="120" />
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 申请免学费弹窗 -->
|
||||
<el-dialog
|
||||
title="申请免学费"
|
||||
v-model="applyDialogVisible"
|
||||
:width="500"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="applyFormRef"
|
||||
:model="applyForm"
|
||||
:rules="applyRules"
|
||||
label-width="120px">
|
||||
<el-form-item label="批次" prop="termId">
|
||||
<el-select
|
||||
v-model="applyForm.termId"
|
||||
placeholder="请选择批次"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in termList"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="applyDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :disabled="applyLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="TuitionFreeStuApply">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, applyObj } from "/@/api/stuwork/tuitionfreestuapply";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import request from '/@/utils/request'
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
const applyFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const classList = ref<any[]>([])
|
||||
const termList = ref<any[]>([])
|
||||
const genderList = ref<any[]>([])
|
||||
const educationList = ref<any[]>([])
|
||||
const majorLevelList = ref<any[]>([])
|
||||
const selectedRows = ref<any[]>([])
|
||||
const applyDialogVisible = ref(false)
|
||||
const applyLoading = ref(false)
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 申请表单
|
||||
const applyForm = reactive({
|
||||
termId: ''
|
||||
})
|
||||
|
||||
// 申请表单验证规则
|
||||
const applyRules = {
|
||||
termId: [
|
||||
{ required: true, message: '请选择批次', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
classCode: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化性别
|
||||
const formatGender = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = genderList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化生源
|
||||
const formatEducation = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = educationList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化层次
|
||||
const formatMajorLevel = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = majorLevelList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 表格选择变化
|
||||
const handleSelectionChange = (selection: any[]) => {
|
||||
selectedRows.value = selection
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.classCode = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 申请免学费
|
||||
const handleApply = () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
useMessage().warning('请至少选择一名学生')
|
||||
return
|
||||
}
|
||||
applyDialogVisible.value = true
|
||||
applyForm.termId = ''
|
||||
}
|
||||
|
||||
// 提交申请
|
||||
const handleSubmit = async () => {
|
||||
if (!applyFormRef.value) return
|
||||
|
||||
await applyFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
applyLoading.value = true
|
||||
try {
|
||||
const { confirm } = useMessageBox()
|
||||
await confirm(`确定要为选中的 ${selectedRows.value.length} 名学生申请免学费吗?`)
|
||||
|
||||
const studentIds = selectedRows.value.map((row: any) => row.id || row.stuNo)
|
||||
await applyObj({
|
||||
termId: applyForm.termId,
|
||||
studentIds: studentIds
|
||||
})
|
||||
useMessage().success('申请成功')
|
||||
applyDialogVisible.value = false
|
||||
selectedRows.value = []
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '申请失败')
|
||||
}
|
||||
} finally {
|
||||
applyLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取批次列表
|
||||
const getTermList = async () => {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/stuwork/tuitionfreeterm/list',
|
||||
method: 'get'
|
||||
})
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
termList.value = res.data
|
||||
} else {
|
||||
termList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取批次列表失败', err)
|
||||
termList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取性别字典
|
||||
const getGenderDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('sexy')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
genderList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
genderList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取性别字典失败', err)
|
||||
genderList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取生源字典
|
||||
const getEducationDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('pre_school_education')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
educationList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
educationList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取生源字典失败', err)
|
||||
educationList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取层次字典
|
||||
const getMajorLevelDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('basic_major_level')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
majorLevelList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
majorLevelList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取层次字典失败', err)
|
||||
majorLevelList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getTermList()
|
||||
getClassListData()
|
||||
getGenderDict()
|
||||
getEducationDict()
|
||||
getMajorLevelDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
306
src/views/stuwork/tuitionfreestu/approve.vue
Normal file
306
src/views/stuwork/tuitionfreestu/approve.vue
Normal file
@@ -0,0 +1,306 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="批次" prop="termId">
|
||||
<el-select
|
||||
v-model="state.queryForm.termId"
|
||||
placeholder="请选择批次"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in termList"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- Tab切换 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
|
||||
<el-tab-pane label="免学费审批" name="pending"></el-tab-pane>
|
||||
<el-tab-pane label="已审批" name="approved"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 免学费审批表格 -->
|
||||
<el-table
|
||||
v-if="activeTab === 'pending'"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="termTitle" label="免学费批次" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="majorName" label="专业名称" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="classNo" label="班号" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="teacherName" label="班主任" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="num" label="人数" show-overflow-tooltip align="center" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.num !== undefined && scope.row.num !== null ? scope.row.num : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleViewDetail(scope.row)">
|
||||
查看详情
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 已审批表格(带合计) -->
|
||||
<el-table
|
||||
v-if="activeTab === 'approved'"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
show-summary
|
||||
:summary-method="getSummaries">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="termTitle" label="免学费批次" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="classNum" label="申报班级数" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.classNum !== undefined && scope.row.classNum !== null ? scope.row.classNum : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="stuNum" label="申报人数" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.stuNum !== undefined && scope.row.stuNum !== null ? scope.row.stuNum : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleViewDetail(scope.row)">
|
||||
查看详情
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 查看详情弹窗 -->
|
||||
<detail-dialog ref="detailDialogRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="TuitionFreeStuApprove">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { getApproveData, getApprovedData } from "/@/api/stuwork/tuitionfreestuapprove";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import request from '/@/utils/request'
|
||||
import DetailDialog from './detail.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
const detailDialogRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const activeTab = ref('pending')
|
||||
const termList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
termId: '',
|
||||
deptCode: '',
|
||||
classCode: ''
|
||||
},
|
||||
pageList: getApproveData,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// Tab切换
|
||||
const handleTabChange = (tabName: string) => {
|
||||
if (tabName === 'pending') {
|
||||
state.pageList = getApproveData
|
||||
} else {
|
||||
state.pageList = getApprovedData
|
||||
}
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 合计方法(仅用于已审批表格)
|
||||
const getSummaries = (param: any) => {
|
||||
const { columns, data } = param
|
||||
const sums: any[] = []
|
||||
columns.forEach((column: any, index: number) => {
|
||||
if (index === 0) {
|
||||
sums[index] = '合计'
|
||||
return
|
||||
}
|
||||
if (column.property === 'classNum' || column.property === 'stuNum') {
|
||||
const values = data.map((item: any) => Number(item[column.property] || 0))
|
||||
const sum = values.reduce((prev: number, curr: number) => {
|
||||
return prev + curr
|
||||
}, 0)
|
||||
sums[index] = sum
|
||||
} else {
|
||||
sums[index] = ''
|
||||
}
|
||||
})
|
||||
return sums
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.termId = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.classCode = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const handleViewDetail = (row: any) => {
|
||||
detailDialogRef.value?.openDialog(row)
|
||||
}
|
||||
|
||||
// 获取批次列表
|
||||
const getTermList = async () => {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/stuwork/tuitionfreeterm/list',
|
||||
method: 'get'
|
||||
})
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
termList.value = res.data
|
||||
} else {
|
||||
termList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取批次列表失败', err)
|
||||
termList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getTermList()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
70
src/views/stuwork/tuitionfreestu/detail.vue
Normal file
70
src/views/stuwork/tuitionfreestu/detail.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="查看详情"
|
||||
v-model="visible"
|
||||
:close-on-click-modal="false"
|
||||
draggable
|
||||
width="800px">
|
||||
<div v-loading="loading" class="detail-container" v-if="detailData">
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="免学费批次" :span="2">
|
||||
{{ detailData.termTitle || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="学院">
|
||||
{{ detailData.deptName || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="专业名称">
|
||||
{{ detailData.majorName || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="班号">
|
||||
{{ detailData.classNo || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="班主任">
|
||||
{{ detailData.teacherName || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="人数" v-if="detailData.num !== undefined">
|
||||
{{ detailData.num !== null ? detailData.num : '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="申报班级数" v-if="detailData.classNum !== undefined">
|
||||
{{ detailData.classNum !== null ? detailData.classNum : '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="申报人数" v-if="detailData.stuNum !== undefined">
|
||||
{{ detailData.stuNum !== null ? detailData.stuNum : '-' }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="TuitionFreeStuApproveDetailDialog">
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 定义变量内容
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const detailData = ref<any>({})
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
visible.value = true
|
||||
loading.value = false
|
||||
detailData.value = row || {}
|
||||
}
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.detail-container {
|
||||
padding: 20px 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
492
src/views/stuwork/tuitionfreestu/index.vue
Normal file
492
src/views/stuwork/tuitionfreestu/index.vue
Normal file
@@ -0,0 +1,492 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="批次" prop="termId">
|
||||
<el-select
|
||||
v-model="state.queryForm.termId"
|
||||
placeholder="请选择批次"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in termList"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学院" prop="deptCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.deptCode"
|
||||
placeholder="请选择学院"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in deptList"
|
||||
:key="item.deptCode"
|
||||
:label="item.deptName"
|
||||
:value="item.deptCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="入学年份" prop="grade">
|
||||
<el-select
|
||||
v-model="state.queryForm.grade"
|
||||
placeholder="请选择入学年份"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in gradeList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="年纪" prop="gradeCurr">
|
||||
<el-input-number
|
||||
v-model="state.queryForm.gradeCurr"
|
||||
placeholder="请输入年纪"
|
||||
:min="1"
|
||||
:max="10"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select
|
||||
v-model="state.queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态" prop="checkStatus">
|
||||
<el-select
|
||||
v-model="state.queryForm.checkStatus"
|
||||
placeholder="请选择审核状态"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in checkStatusList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="handleAdd">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="primary"
|
||||
plain
|
||||
class="ml10"
|
||||
:loading="exportLoading"
|
||||
@click="handleExport">
|
||||
导出
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="majorName" label="专业" show-overflow-tooltip align="center" min-width="150" />
|
||||
<el-table-column prop="teacherName" label="班主任" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="grade" label="入学年份" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="gradeCurr" label="年级" show-overflow-tooltip align="center" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.gradeCurr !== undefined && scope.row.gradeCurr !== null ? scope.row.gradeCurr : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="classNo" label="班级" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="stuNo" label="学号" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" width="100" />
|
||||
<el-table-column prop="gender" label="性别" show-overflow-tooltip align="center" width="80">
|
||||
<template #default="scope">
|
||||
<span>{{ formatGender(scope.row.gender) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="education" label="生源" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatEducation(scope.row.education) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="majorLevel" label="层次" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatMajorLevel(scope.row.majorLevel) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="phone" label="联系电话" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="money" label="金额" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.money !== undefined && scope.row.money !== null ? scope.row.money : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="checkStatus" label="审核状态" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatCheckStatus(scope.row.checkStatus) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<!-- <form-dialog ref="formDialogRef" @refresh="getDataList" /> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="TuitionFreeStu">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, exportExcel, delObj, getDetail } from "/@/api/stuwork/tuitionfreestu";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import request from '/@/utils/request'
|
||||
import axios from 'axios'
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref()
|
||||
const formDialogRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const exportLoading = ref(false)
|
||||
const termList = ref<any[]>([])
|
||||
const deptList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const gradeList = ref<any[]>([])
|
||||
const genderList = ref<any[]>([])
|
||||
const educationList = ref<any[]>([])
|
||||
const majorLevelList = ref<any[]>([])
|
||||
const checkStatusList = ref<any[]>([
|
||||
{ label: '待审核', value: '0' },
|
||||
{ label: '审核通过', value: '1' }
|
||||
])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
termId: '',
|
||||
deptCode: '',
|
||||
grade: '',
|
||||
gradeCurr: undefined,
|
||||
classCode: '',
|
||||
checkStatus: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化性别
|
||||
const formatGender = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = genderList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化生源
|
||||
const formatEducation = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = educationList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化层次
|
||||
const formatMajorLevel = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = majorLevelList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化审核状态
|
||||
const formatCheckStatus = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = checkStatusList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.termId = ''
|
||||
state.queryForm.deptCode = ''
|
||||
state.queryForm.grade = ''
|
||||
state.queryForm.gradeCurr = undefined
|
||||
state.queryForm.classCode = ''
|
||||
state.queryForm.checkStatus = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 新增
|
||||
const handleAdd = () => {
|
||||
useMessage().info('新增功能待开发')
|
||||
// formDialogRef.value?.openDialog('add')
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
useMessage().info('编辑功能待开发')
|
||||
// formDialogRef.value?.openDialog('edit', row.id)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
try {
|
||||
const { confirm } = useMessageBox()
|
||||
await confirm(`确定要删除学号为 ${row.stuNo} 的免学费记录吗?`)
|
||||
await delObj(row.id)
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
exportLoading.value = true
|
||||
const res = await exportExcel(state.queryForm)
|
||||
const blob = new Blob([res.data as BlobPart])
|
||||
const fileName = `免学费查询_${new Date().getTime()}.xls`
|
||||
const elink = document.createElement('a')
|
||||
elink.download = fileName
|
||||
elink.style.display = 'none'
|
||||
elink.href = URL.createObjectURL(blob)
|
||||
document.body.appendChild(elink)
|
||||
elink.click()
|
||||
URL.revokeObjectURL(elink.href)
|
||||
document.body.removeChild(elink)
|
||||
useMessage().success('导出成功')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
} finally {
|
||||
exportLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取批次列表
|
||||
const getTermList = async () => {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/stuwork/tuitionfreeterm/list',
|
||||
method: 'get'
|
||||
})
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
termList.value = res.data
|
||||
} else {
|
||||
termList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取批次列表失败', err)
|
||||
termList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
try {
|
||||
const res = await getDeptList()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
deptList.value = res.data
|
||||
} else {
|
||||
deptList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学院列表失败', err)
|
||||
deptList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取班级列表
|
||||
const getClassListData = async () => {
|
||||
try {
|
||||
const res = await getClassListByRole()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
classList.value = res.data
|
||||
} else {
|
||||
classList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取班级列表失败', err)
|
||||
classList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取入学年份列表
|
||||
const getGradeList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
gradeList.value = res.data
|
||||
} else {
|
||||
gradeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取入学年份列表失败', err)
|
||||
gradeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取性别字典
|
||||
const getGenderDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('sexy')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
genderList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
genderList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取性别字典失败', err)
|
||||
genderList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取生源字典
|
||||
const getEducationDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('pre_school_education')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
educationList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
educationList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取生源字典失败', err)
|
||||
educationList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取层次字典
|
||||
const getMajorLevelDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('basic_major_level')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
majorLevelList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
majorLevelList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取层次字典失败', err)
|
||||
majorLevelList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getTermList()
|
||||
getDeptListData()
|
||||
getClassListData()
|
||||
getGradeList()
|
||||
getGenderDict()
|
||||
getEducationDict()
|
||||
getMajorLevelDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
328
src/views/stuwork/tuitionfreeterm/form.vue
Normal file
328
src/views/stuwork/tuitionfreeterm/form.vue
Normal file
@@ -0,0 +1,328 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="form.id ? '编辑批次' : '新增批次'"
|
||||
v-model="visible"
|
||||
:width="800"
|
||||
:close-on-click-modal="false"
|
||||
draggable>
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:model="form"
|
||||
:rules="dataRules"
|
||||
label-width="120px"
|
||||
v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="批次名称" prop="title">
|
||||
<el-input
|
||||
v-model="form.title"
|
||||
placeholder="请输入批次名称"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="form.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
:disabled="!!form.id">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="form.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
:disabled="!!form.id">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="上报开始日期" prop="startTime">
|
||||
<el-date-picker
|
||||
v-model="form.startTime"
|
||||
type="date"
|
||||
placeholder="请输入上报开始日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="上报截止日期" prop="endTime">
|
||||
<el-date-picker
|
||||
v-model="form.endTime"
|
||||
type="date"
|
||||
placeholder="请输入上报截止日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item label="类别" prop="type">
|
||||
<el-select
|
||||
v-model="form.type"
|
||||
placeholder="请选择类别"
|
||||
clearable
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in typeList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="excel表头" prop="excelTitle">
|
||||
<el-input
|
||||
v-model="form.excelTitle"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入excel表头"
|
||||
clearable
|
||||
style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="TuitionFreeTermFormDialog">
|
||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
import { addObj, editObj, getDetail } from '/@/api/stuwork/tuitionfreeterm'
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear'
|
||||
import { getDicts } from '/@/api/admin/dict'
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
const operType = ref('add')
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([])
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
id: '',
|
||||
title: '',
|
||||
schoolYear: '',
|
||||
schoolTerm: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
type: '',
|
||||
excelTitle: ''
|
||||
})
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = {
|
||||
title: [
|
||||
{ required: true, message: '请输入批次名称', trigger: 'blur' }
|
||||
],
|
||||
schoolYear: [
|
||||
{ required: true, message: '请选择学年', trigger: 'change' }
|
||||
],
|
||||
schoolTerm: [
|
||||
{ required: true, message: '请选择学期', trigger: 'change' }
|
||||
],
|
||||
startTime: [
|
||||
{ required: true, message: '请输入上报开始日期', trigger: 'change' }
|
||||
],
|
||||
endTime: [
|
||||
{ required: true, message: '请输入上报截止日期', trigger: 'change' }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: '请选择类别', trigger: 'change' }
|
||||
],
|
||||
excelTitle: [
|
||||
{ required: true, message: '请输入excel表头', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类别字典
|
||||
const getTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('tuition_free_term_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
typeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
typeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类别字典失败', err)
|
||||
typeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (type: string = 'add', row?: any) => {
|
||||
operType.value = type
|
||||
visible.value = true
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields()
|
||||
form.id = ''
|
||||
form.title = ''
|
||||
form.schoolYear = ''
|
||||
form.schoolTerm = ''
|
||||
form.startTime = ''
|
||||
form.endTime = ''
|
||||
form.type = ''
|
||||
form.excelTitle = ''
|
||||
|
||||
// 编辑时填充数据
|
||||
if (type === 'edit' && row) {
|
||||
form.id = row.id
|
||||
form.title = row.title || ''
|
||||
form.schoolYear = row.schoolYear || ''
|
||||
form.schoolTerm = row.schoolTerm || ''
|
||||
form.startTime = row.startTime || ''
|
||||
form.endTime = row.endTime || ''
|
||||
form.type = row.type || ''
|
||||
form.excelTitle = row.excelTitle || ''
|
||||
|
||||
// 如果需要获取详情
|
||||
if (row.id && (!row.title || !row.schoolYear)) {
|
||||
loading.value = true
|
||||
getDetail(row.id).then((res: any) => {
|
||||
if (res.data) {
|
||||
form.title = res.data.title || ''
|
||||
form.schoolYear = res.data.schoolYear || ''
|
||||
form.schoolTerm = res.data.schoolTerm || ''
|
||||
form.startTime = res.data.startTime || ''
|
||||
form.endTime = res.data.endTime || ''
|
||||
form.type = res.data.type || ''
|
||||
form.excelTitle = res.data.excelTitle || ''
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('获取详情失败', err)
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const onSubmit = async () => {
|
||||
if (!dataFormRef.value) return
|
||||
|
||||
await dataFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
try {
|
||||
const submitData = {
|
||||
title: form.title,
|
||||
schoolYear: form.schoolYear,
|
||||
schoolTerm: form.schoolTerm,
|
||||
startTime: form.startTime,
|
||||
endTime: form.endTime,
|
||||
type: form.type,
|
||||
excelTitle: form.excelTitle
|
||||
}
|
||||
|
||||
if (operType.value === 'edit' && form.id) {
|
||||
await editObj({ ...submitData, id: form.id })
|
||||
useMessage().success('编辑成功')
|
||||
} else {
|
||||
await addObj(submitData)
|
||||
useMessage().success('新增成功')
|
||||
}
|
||||
|
||||
visible.value = false
|
||||
emit('refresh')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || (operType.value === 'edit' ? '编辑失败' : '新增失败'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getTypeDict()
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
277
src/views/stuwork/tuitionfreeterm/index.vue
Normal file
277
src/views/stuwork/tuitionfreeterm/index.vue
Normal file
@@ -0,0 +1,277 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select
|
||||
v-model="state.queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="Search" @click="getDataList">查询</el-button>
|
||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
icon="Plus"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
@click="formDialogRef.openDialog()">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10 mr20"
|
||||
style="float: right;"
|
||||
@queryTable="getDataList">
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="title" label="批次名称" show-overflow-tooltip align="center" min-width="200" />
|
||||
<el-table-column prop="schoolYear" label="学年" show-overflow-tooltip align="center" width="120" />
|
||||
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ formatSchoolTerm(scope.row.schoolTerm) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="startTime" label="上报开始日期" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="endTime" label="上报截止日期" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" label="类别" show-overflow-tooltip align="center" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ formatType(scope.row.type) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
icon="Edit"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="Delete"
|
||||
text
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
@size-change="sizeChangeHandle"
|
||||
@current-change="currentChangeHandle"
|
||||
v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="TuitionFreeTerm">
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj } from "/@/api/stuwork/tuitionfreeterm";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
import FormDialog from './form.vue'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const typeList = ref<any[]>([])
|
||||
|
||||
// 表格样式
|
||||
const tableStyle = {
|
||||
cellStyle: { padding: '8px 0' },
|
||||
headerCellStyle: { background: '#f5f7fa', color: '#606266', fontWeight: 'bold' }
|
||||
}
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
schoolYear: '',
|
||||
schoolTerm: ''
|
||||
},
|
||||
pageList: fetchList,
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
},
|
||||
createdIsNeed: true
|
||||
})
|
||||
|
||||
// table hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle: _tableStyle
|
||||
} = useTable(state)
|
||||
|
||||
// 格式化学期
|
||||
const formatSchoolTerm = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = schoolTermList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 格式化类别
|
||||
const formatType = (value: string | number) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
const dictItem = typeList.value.find(item => item.value == value)
|
||||
return dictItem ? dictItem.label : value
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
state.queryForm.schoolYear = ''
|
||||
state.queryForm.schoolTerm = ''
|
||||
getDataList()
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (row: any) => {
|
||||
const { confirm } = useMessageBox()
|
||||
try {
|
||||
await confirm('确定要删除该批次吗?')
|
||||
await delObj([row.id])
|
||||
useMessage().success('删除成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '删除失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
try {
|
||||
const res = await queryAllSchoolYear()
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolYearList.value = res.data
|
||||
} else {
|
||||
schoolYearList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学年列表失败', err)
|
||||
schoolYearList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取学期字典
|
||||
const getSchoolTermDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('school_term')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
schoolTermList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
schoolTermList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取学期字典失败', err)
|
||||
schoolTermList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取类别字典
|
||||
const getTypeDict = async () => {
|
||||
try {
|
||||
const res = await getDicts('tuition_free_term_type')
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
typeList.value = res.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}))
|
||||
} else {
|
||||
typeList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取类别字典失败', err)
|
||||
typeList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getSchoolYearList()
|
||||
getSchoolTermDict()
|
||||
getTypeDict()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user