Merge branch 'developer' of ssh://code.cyweb.top:30033/scj/zhxy/v3/cloud-ui into developer
This commit is contained in:
7
.gitattributes
vendored
Normal file
7
.gitattributes
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# 确保所有文本文件使用 UTF-8 编码
|
||||||
|
* text=auto eol=lf
|
||||||
|
*.vue text eol=lf charset=utf-8
|
||||||
|
*.ts text eol=lf charset=utf-8
|
||||||
|
*.js text eol=lf charset=utf-8
|
||||||
|
*.json text eol=lf charset=utf-8
|
||||||
|
|
||||||
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({
|
return request({
|
||||||
url: '/stuwork/assessmentcategory/list',
|
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,85 @@
|
|||||||
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/page',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取考核指标列表(不分页)
|
||||||
|
* @param query
|
||||||
|
*/
|
||||||
|
export const getList = (query?: any) => {
|
||||||
return request({
|
return request({
|
||||||
url: '/stuwork/assessmentpoint/list',
|
url: '/stuwork/assessmentpoint/list',
|
||||||
method: 'get'
|
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';
|
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 班级代码
|
* @param classCode 班级代码
|
||||||
*/
|
*/
|
||||||
export const queryClassHonorByClassCode = (classCode: string | number) => {
|
export const queryClassHonorByClassCode = (classCode: string | number) => {
|
||||||
return request({
|
return request({
|
||||||
url: `/stuwork/classhonor/queryClassHonorByClassCode/${classCode}`,
|
url: `/stuwork/classhonor/queryClassHonorByClassCode/${classCode}`,
|
||||||
method: 'get',
|
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';
|
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 班级代码
|
* @param classCode 班级代码
|
||||||
*/
|
*/
|
||||||
export const queryDataByClassCode = (classCode: string | number) => {
|
export const queryDataByClassCode = (classCode: string | number) => {
|
||||||
return request({
|
return request({
|
||||||
url: `/stuwork/classpublicity/queryDataByClassCode/${classCode}`,
|
url: `/stuwork/classpublicity/queryDataByClassCode/${classCode}`,
|
||||||
method: 'get',
|
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>
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
<script setup lang="ts" name="ClassRoomHygieneDailyDialog">
|
<script setup lang="ts" name="ClassRoomHygieneDailyDialog">
|
||||||
import { ref, reactive, nextTick, computed, onMounted } from 'vue'
|
import { ref, reactive, nextTick, computed, onMounted } from 'vue'
|
||||||
import { useMessage } from "/@/hooks/message";
|
import { useMessage } from "/@/hooks/message";
|
||||||
import { getObj, addObj, putObj } from '/@/api/stuwork/classRoomHygieneDaily'
|
import { getObj, addObj, putObj } from '/@/api/stuwork/classroomhygienedaily'
|
||||||
import { getDeptList } from '/@/api/basic/basicclass'
|
import { getDeptList } from '/@/api/basic/basicclass'
|
||||||
import { getClassListByRole, queryClassByDeptCode } from '/@/api/basic/basicclass'
|
import { getClassListByRole, queryClassByDeptCode } from '/@/api/basic/basicclass'
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@
|
|||||||
<script setup lang="ts" name="ClassRoomHygieneDaily">
|
<script setup lang="ts" name="ClassRoomHygieneDaily">
|
||||||
import { ref, reactive, defineAsyncComponent, onMounted } from 'vue'
|
import { ref, reactive, defineAsyncComponent, onMounted } from 'vue'
|
||||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||||
import { fetchList, delObjs } from "/@/api/stuwork/classRoomHygieneDaily";
|
import { fetchList, delObjs } from "/@/api/stuwork/classroomhygienedaily";
|
||||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||||
import { getDeptList } from '/@/api/basic/basicclass'
|
import { getDeptList } from '/@/api/basic/basicclass'
|
||||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
<script setup lang="ts" name="WeekPlanDetail">
|
<script setup lang="ts" name="WeekPlanDetail">
|
||||||
import { ref, reactive, nextTick, defineAsyncComponent } from 'vue'
|
import { ref, reactive, nextTick, defineAsyncComponent } from 'vue'
|
||||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||||
import { getObj, delObjs } from '/@/api/stuwork/weekPlan'
|
import { getObj, delObjs } from '/@/api/stuwork/weekplan'
|
||||||
|
|
||||||
const emit = defineEmits(['refresh']);
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
<script setup lang="ts" name="WeekPlanDialog">
|
<script setup lang="ts" name="WeekPlanDialog">
|
||||||
import { ref, reactive, nextTick, onMounted } from 'vue'
|
import { ref, reactive, nextTick, onMounted } from 'vue'
|
||||||
import { useMessage } from "/@/hooks/message";
|
import { useMessage } from "/@/hooks/message";
|
||||||
import { getObj, addObj, putObj } from '/@/api/stuwork/weekPlan'
|
import { getObj, addObj, putObj } from '/@/api/stuwork/weekplan'
|
||||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear'
|
import { queryAllSchoolYear } from '/@/api/basic/basicyear'
|
||||||
import Editor from '/@/components/Editor/index.vue'
|
import Editor from '/@/components/Editor/index.vue'
|
||||||
|
|
||||||
|
|||||||
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="请选择学院"
|
placeholder="请选择学院"
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
style="width: 200px">
|
style="width: 200px"
|
||||||
|
@change="handleDeptChange">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in deptList"
|
v-for="item in deptList"
|
||||||
:key="item.deptCode"
|
:key="item.deptCode"
|
||||||
@@ -27,7 +28,7 @@
|
|||||||
filterable
|
filterable
|
||||||
style="width: 200px">
|
style="width: 200px">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in classList"
|
v-for="item in filteredClassList"
|
||||||
:key="item.classCode"
|
:key="item.classCode"
|
||||||
:label="item.classNo"
|
:label="item.classNo"
|
||||||
:value="item.classCode">
|
:value="item.classCode">
|
||||||
@@ -72,12 +73,12 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip align="center" width="180">
|
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip align="center" width="180">
|
||||||
<template #default="scope">
|
<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>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="updateTime" label="更新时间" show-overflow-tooltip align="center" width="180">
|
<el-table-column prop="updateTime" label="更新时间" show-overflow-tooltip align="center" width="180">
|
||||||
<template #default="scope">
|
<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>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="150" align="center" fixed="right">
|
<el-table-column label="操作" width="150" align="center" fixed="right">
|
||||||
@@ -103,12 +104,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="PendingWork">
|
<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 { BasicTableProps, useTable } from "/@/hooks/table";
|
||||||
import { fetchList } from "/@/api/stuwork/pendingwork";
|
import { fetchList } from "/@/api/stuwork/pendingwork";
|
||||||
import { getDeptList } from "/@/api/basic/basicclass";
|
import { getDeptList } from "/@/api/basic/basicclass";
|
||||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||||
import { useMessage } from "/@/hooks/message";
|
import { useMessage } from "/@/hooks/message";
|
||||||
|
import { parseTime } from "/@/utils/formatTime";
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
@@ -154,6 +156,11 @@ const handleReset = () => {
|
|||||||
getDataList()
|
getDataList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 学院变化时,清空班级选择并过滤班级列表
|
||||||
|
const handleDeptChange = () => {
|
||||||
|
searchForm.classCode = ''
|
||||||
|
}
|
||||||
|
|
||||||
// 查看详情
|
// 查看详情
|
||||||
const handleView = (row: any) => {
|
const handleView = (row: any) => {
|
||||||
useMessage().warning('查看详情功能待实现')
|
useMessage().warning('查看详情功能待实现')
|
||||||
@@ -179,6 +186,8 @@ const getClassListData = async () => {
|
|||||||
const res = await getClassListByRole()
|
const res = await getClassListByRole()
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
classList.value = Array.isArray(res.data) ? res.data : []
|
classList.value = Array.isArray(res.data) ? res.data : []
|
||||||
|
} else {
|
||||||
|
classList.value = []
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('获取班级列表失败', 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(() => {
|
onMounted(() => {
|
||||||
getDeptListData()
|
getDeptListData()
|
||||||
@@ -193,3 +210,6 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</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>
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user