This commit is contained in:
guochunsi
2026-01-15 11:39:10 +08:00
70 changed files with 63145 additions and 6179 deletions

File diff suppressed because one or more lines are too long

View File

@@ -23,7 +23,9 @@ export function getDictsByTypes(types: string[]) {
return request({ return request({
url: '/admin/dict/item/typeList', url: '/admin/dict/item/typeList',
method: 'post', method: 'post',
data: types, data: {
typeList: types,
},
}); });
} }
@@ -165,6 +167,8 @@ export function queryDictByTypeList(types: string[]) {
return request({ return request({
url: '/admin/dict/queryDictByTypeList', url: '/admin/dict/queryDictByTypeList',
method: 'post', method: 'post',
data: types, data: {
typeList: types,
},
}); });
} }

View File

@@ -1,12 +1,12 @@
import request from '/@/utils/request'; import request from '/@/utils/request';
/** /**
* 获取学生证件照列表(分页) * 获取学生证件照列表
* @param query * @param query
*/ */
export const fetchList = (query?: any) => { export const fetchList = (query?: any) => {
return request({ return request({
url: '/basic/basicstudent/avatar/page', url: '/basic/basicstudent/avatar/list',
method: 'get', method: 'get',
params: query, params: query,
}); });

View File

@@ -1,119 +0,0 @@
import request from '/@/utils/request';
/**
* 获取列表
* @param query
*/
export const fetchList = (query?: any) => {
return request({
url: '/recruit/recruitplanmajor/page',
method: 'get',
params: query,
});
};
/**
* 列表
* @param query
*/
export const list = (query?: any) => {
return request({
url: '/recruit/recruitplanmajor/list',
method: 'get',
params: query,
});
};
/**
* 按统计获取列表
* @param query
*/
export const fetchListByStatic = (query?: any) => {
return request({
url: '/recruit/recruitplanmajor/fetchListByStatic',
method: 'get',
params: query,
});
};
/**
* 按教育程度列表
* @param query
*/
export const listByEdu = (query?: any) => {
return request({
url: '/recruit/recruitplanmajor/listByEdu',
method: 'get',
params: query,
});
};
/**
* 列表(城市)
* @param query
*/
export const listcz = (query?: any) => {
return request({
url: '/recruit/recruitplanmajor/listcz',
method: 'get',
params: query,
});
};
/**
* 新增
* @param obj
*/
export const addObj = (obj: any) => {
return request({
url: '/recruit/recruitplanmajor',
method: 'post',
data: obj,
});
};
/**
* 获取详情
* @param id
*/
export const getObj = (id: string | number) => {
return request({
url: `/recruit/recruitplanmajor/${id}`,
method: 'get',
});
};
/**
* 获取城市计划
* @param obj
*/
export const getCityPlan = (obj?: any) => {
return request({
url: '/recruit/recruitplanmajor/getCityPlan',
method: 'get',
params: obj,
});
};
/**
* 删除
* @param id
*/
export const delObj = (id: string | number) => {
return request({
url: `/recruit/recruitplanmajor/${id}`,
method: 'delete',
});
};
/**
* 更新
* @param obj
*/
export const putObj = (obj: any) => {
return request({
url: '/recruit/recruitplanmajor',
method: 'put',
data: obj,
});
};

View File

@@ -18,7 +18,7 @@ export const fetchList = (query?: any) => {
*/ */
export const addObj = (obj: any) => { export const addObj = (obj: any) => {
return request({ return request({
url: '/recruit/recruitstudentplan', url: '/recruit/recruitstudentplan/add',
method: 'post', method: 'post',
data: obj, data: obj,
}); });
@@ -30,8 +30,9 @@ export const addObj = (obj: any) => {
*/ */
export const getObj = (id: string | number) => { export const getObj = (id: string | number) => {
return request({ return request({
url: `/recruit/recruitstudentplan/${id}`, url: `/recruit/recruitstudentplan/getById`,
method: 'get', method: 'get',
params: { id :id},
}); });
}; };
@@ -41,8 +42,9 @@ export const getObj = (id: string | number) => {
*/ */
export const delObj = (id: string | number) => { export const delObj = (id: string | number) => {
return request({ return request({
url: `/recruit/recruitstudentplan/${id}`, url: `/recruit/recruitstudentplan/deletById`,
method: 'delete', method: 'post',
data: { id :id},
}); });
}; };
@@ -52,8 +54,58 @@ export const delObj = (id: string | number) => {
*/ */
export const putObj = (obj: any) => { export const putObj = (obj: any) => {
return request({ return request({
url: '/recruit/recruitstudentplan', url: '/recruit/recruitstudentplan/edit',
method: 'put', method: 'post',
data: obj, data: obj,
}); });
}; };
/**
* 单字段快速更新
* @param obj
*/
export const editQuickField = (obj: any) => {
return request({
url: '/recruit/recruitstudentplan/editQuickField',
method: 'post',
data: obj,
});
};
/**
* 按教育程度列表
* @param query
*/
export const listByEdu = (query?: any) => {
return request({
url: '/recruit/recruitstudentplan/listByEdu',
method: 'get',
params: query,
});
};
/**
* 按学历列表 初中
* @param query
*/
export const listcz = (query?: any) => {
return request({
url: '/recruit/recruitstudentplan/listcz',
method: 'get',
params: query,
});
};
/**
* 列表
* @param query
*/
export const listPlanByCondition = (query?: any) => {
return request({
url: '/recruit/recruitstudentplan/listPlanByCondition',
method: 'get',
params: query,
});
};

View File

@@ -5,7 +5,7 @@ import request from '/@/utils/request';
*/ */
export const fetchList = (query: any) => { export const fetchList = (query: any) => {
return request({ return request({
url: '/stuwork/classhygienedaily/page', url: '/stuwork/classhygienedailyanalysis/queryClassHygieneDailyAnalysis',
method: 'get', method: 'get',
params: query params: query
}); });

View File

@@ -1,5 +1,16 @@
import request from '/@/utils/request'; import request from '/@/utils/request';
/**
* 分页查询宿舍楼列表
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/dormbuilding/newPage',
method: 'get',
params: query
});
};
/** /**
* 获取楼号列表 * 获取楼号列表
*/ */
@@ -10,3 +21,47 @@ export const getBuildingList = () => {
}); });
}; };
/**
* 新增宿舍楼
*/
export const addObj = (data: any) => {
return request({
url: '/stuwork/dormbuilding',
method: 'post',
data
});
};
/**
* 编辑宿舍楼
*/
export const putObj = (data: any) => {
return request({
url: '/stuwork/dormbuilding/edit',
method: 'post',
data
});
};
/**
* 删除宿舍楼
*/
export const delObjs = (ids: string[]) => {
return request({
url: '/stuwork/dormbuilding/delete',
method: 'post',
data: ids
});
};
/**
* 获取宿舍楼详情
*/
export const getObj = (id: string) => {
return request({
url: `/stuwork/dormbuilding/detail`,
method: 'get',
params: { id }
});
};

View File

@@ -0,0 +1,24 @@
import request from '/@/utils/request';
/**
* 分页查询宿舍管理员列表
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/dormbuildingmanger/page',
method: 'get',
params: query
});
};
/**
* 删除宿舍管理员
*/
export const delObjs = (ids: string[]) => {
return request({
url: '/stuwork/dormbuildingmanger/delete',
method: 'post',
data: ids
});
};

View File

@@ -0,0 +1,57 @@
import request from '/@/utils/request';
/**
* 分页查询日卫生检查列表
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/dormhygienedaily/page',
method: 'get',
params: query
});
};
/**
* 新增日卫生检查
*/
export const addObj = (data: any) => {
return request({
url: '/stuwork/dormhygienedaily',
method: 'post',
data
});
};
/**
* 编辑日卫生检查
*/
export const putObj = (data: any) => {
return request({
url: '/stuwork/dormhygienedaily/edit',
method: 'post',
data
});
};
/**
* 删除日卫生检查
*/
export const delObjs = (ids: string[]) => {
return request({
url: '/stuwork/dormhygienedaily/delete',
method: 'post',
data: ids
});
};
/**
* 获取日卫生检查详情
*/
export const getObj = (id: string) => {
return request({
url: `/stuwork/dormhygienedaily/detail`,
method: 'get',
params: { id }
});
};

View File

@@ -0,0 +1,57 @@
import request from '/@/utils/request';
/**
* 分页查询月卫生检查整改列表
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/dormreform/page',
method: 'get',
params: query
});
};
/**
* 新增月卫生检查整改
*/
export const addObj = (data: any) => {
return request({
url: '/stuwork/dormreform',
method: 'post',
data
});
};
/**
* 编辑月卫生检查整改
*/
export const putObj = (data: any) => {
return request({
url: '/stuwork/dormreform/edit',
method: 'post',
data
});
};
/**
* 删除月卫生检查整改
*/
export const delObjs = (ids: string[]) => {
return request({
url: '/stuwork/dormreform/delete',
method: 'post',
data: ids
});
};
/**
* 获取月卫生检查整改详情
*/
export const getObj = (id: string) => {
return request({
url: `/stuwork/dormreform/detail`,
method: 'get',
params: { id }
});
};

View File

@@ -0,0 +1,89 @@
import request from '/@/utils/request';
/**
* 分页查询宿舍房间列表
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/dormroom/page',
method: 'get',
params: query
});
};
/**
* 新增宿舍房间
*/
export const addObj = (data: any) => {
return request({
url: '/stuwork/dormroom',
method: 'post',
data
});
};
/**
* 编辑宿舍房间
*/
export const putObj = (data: any) => {
return request({
url: '/stuwork/dormroom/edit',
method: 'post',
data
});
};
/**
* 删除宿舍房间
*/
export const delObj = (id: string) => {
return request({
url: `/stuwork/dormroom/delete`,
method: 'post',
data: [id]
});
};
/**
* 学院安排
*/
export const editDept = (data: { deptCode: string; ids: string[] }) => {
return request({
url: '/stuwork/dormroom/editDept',
method: 'post',
data
});
};
/**
* 获取宿舍房间详情
*/
export const getObj = (id: string) => {
return request({
url: `/stuwork/dormroom/${id}`,
method: 'get'
});
};
/**
* 获取宿舍号选择列表
*/
export const getRoomList = () => {
return request({
url: '/stuwork/dormroom/list',
method: 'get'
});
};
/**
* 获取宿舍树状列表
* @param dormdataType 宿舍空几人类型
*/
export const fetchDormRoomTreeList = (dormdataType?: string) => {
return request({
url: '/stuwork/dormroom/fetchDormRoomTreeList',
method: 'get',
params: { dormdataType }
});
};

View File

@@ -11,3 +11,94 @@ export const fearchStuNumByClassCode = (classCode: string | number) => {
}); });
}; };
/**
* 查询空宿舍列表
* @param buildingNo 楼号
*/
export const queryEmptyRoomWithBuildingNo = (buildingNo: string) => {
return request({
url: '/stuwork/dormroomstudent/queryEmptyRoomWithBuildingNo',
method: 'get',
params: { buildingNo }
});
};
/**
* 查询空几人宿舍列表
* @param buildingNo 楼号
* @param roomType 空几人1-5
*/
export const queryEmtryRoomDetail = (buildingNo: string, roomType: string) => {
return request({
url: '/stuwork/dormroomstudent/queryEmtryRoomDetail',
method: 'get',
params: { buildingNo, roomType }
});
};
/**
* 查询异常住宿学生列表
*/
export const queryStudentAbnormal = () => {
return request({
url: '/stuwork/dormroomstudent/queryStudentAbnormal',
method: 'get'
});
};
/**
* 分页查询住宿学生列表
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/dormroomstudent/page',
method: 'get',
params: query
});
};
/**
* 新增住宿学生
*/
export const addObj = (data: any) => {
return request({
url: '/stuwork/dormroomstudent',
method: 'post',
data
});
};
/**
* 转宿
*/
export const editObj = (data: any) => {
return request({
url: '/stuwork/dormroomstudent/edit',
method: 'post',
data
});
};
/**
* 退宿
*/
export const delObjs = (ids: string[]) => {
return request({
url: '/stuwork/dormroomstudent/delete',
method: 'post',
data: ids
});
};
/**
* 获取床位号列表
* @param roomNo 宿舍号
*/
export const fearchRoomStuNum = (roomNo: string) => {
return request({
url: '/stuwork/dormroomstudent/fearchRoomStuNum',
method: 'get',
params: { roomNo }
});
};

View File

@@ -0,0 +1,14 @@
import request from '/@/utils/request';
/**
* 获取待办工作列表
* @param query 查询参数
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/pendingwork/getPendingWork',
method: 'get',
params: query
});
};

View File

@@ -0,0 +1,46 @@
import request from '/@/utils/request';
/**
* 分页查询工学交替列表
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/stuworkstudyalternate/page',
method: 'get',
params: query
});
};
/**
* 新增工学交替
*/
export const addObj = (data: any) => {
return request({
url: '/stuwork/stuworkstudyalternate',
method: 'post',
data
});
};
/**
* 指定带班教师
*/
export const chooseTeacherAttendance = (data: any) => {
return request({
url: '/stuwork/stuworkstudyalternate/chooseTeacherAttendance',
method: 'post',
data
});
};
/**
* 删除工学交替
*/
export const delObj = (ids: string[]) => {
return request({
url: '/stuwork/stuworkstudyalternate/delete',
method: 'post',
data: ids
});
};

View File

@@ -0,0 +1,57 @@
import request from '/@/utils/request';
/**
* 分页查询宿舍水电明细列表
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/waterdetail/page',
method: 'get',
params: query
});
};
/**
* 新增宿舍水电明细
*/
export const addObj = (data: any) => {
return request({
url: '/stuwork/waterdetail',
method: 'post',
data
});
};
/**
* 编辑宿舍水电明细
*/
export const putObj = (data: any) => {
return request({
url: '/stuwork/waterdetail/edit',
method: 'post',
data
});
};
/**
* 删除宿舍水电明细
*/
export const delObjs = (ids: string[]) => {
return request({
url: '/stuwork/waterdetail/delete',
method: 'post',
data: ids
});
};
/**
* 初始化本期水电补贴
*/
export const initWaterOrder = (data: { costMoney: number }) => {
return request({
url: '/stuwork/waterdetail/initWaterOrder',
method: 'post',
data
});
};

View File

@@ -0,0 +1,14 @@
import request from '/@/utils/request';
/**
* 查看水电明细
* @param roomNo 宿舍号
*/
export const lookDetails = (roomNo: string) => {
return request({
url: '/stuwork/watermonthreport/lookDetails',
method: 'get',
params: { roomNo }
});
};

View File

@@ -0,0 +1,67 @@
import request from '/@/utils/request';
/**
* 分页查询水电充值订单列表
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/waterorder/page',
method: 'get',
params: query
});
};
/**
* 新增水电充值订单
*/
export const addObj = (data: any) => {
return request({
url: '/stuwork/waterorder',
method: 'post',
data
});
};
/**
* 编辑水电充值订单
*/
export const putObj = (data: any) => {
return request({
url: '/stuwork/waterorder/edit',
method: 'post',
data
});
};
/**
* 删除水电充值订单
*/
export const delObjs = (ids: string[]) => {
return request({
url: '/stuwork/waterorder/delete',
method: 'post',
data: ids
});
};
/**
* 获取水电充值订单详情
*/
export const getObj = (id: string) => {
return request({
url: '/stuwork/waterorder/detail',
method: 'get',
params: { id }
});
};
/**
* 获取宿舍号列表
*/
export const getRoomList = () => {
return request({
url: '/stuwork/dormroom/list',
method: 'get'
});
};

View File

@@ -0,0 +1,35 @@
import request from '/@/utils/request';
/**
* 分页查询工学交替考勤列表
*/
export const fetchList = (query?: any) => {
return request({
url: '/stuwork/stuworkstudyalternate/page',
method: 'get',
params: query
});
};
/**
* 查询考勤记录
*/
export const queryHistoryList = (data: any) => {
return request({
url: '/stuwork/workstudyattendance/queryHistoryList',
method: 'post',
data
});
};
/**
* 提交考勤
*/
export const submitAttendance = (data: any[]) => {
return request({
url: '/stuwork/workstudyattendance',
method: 'post',
data
});
};

View File

@@ -99,14 +99,19 @@ function initHandle() {
/** /**
* 点击某一节点时触发的事件,更新当前的选中值和展开状态。 * 点击某一节点时触发的事件,更新当前的选中值和展开状态。
* @param {Object} data - 被点击的节点数据
* @param {Object} node - 被点击的节点对象 * @param {Object} node - 被点击的节点对象
*/ */
function handleNodeClick(node) { function handleNodeClick(data, node) {
valueTitle.value = node[props.objMap.label]; // el-tree 的 node-click 事件传递 (data, node) 两个参数
valueId.value = node[props.objMap.value]; const nodeData = data || (node && node.data) || node;
defaultExpandedKey.value = []; if (nodeData) {
proxy.$refs.treeSelect.blur(); valueTitle.value = nodeData[props.objMap.label] || nodeData[props.objMap.value] || '';
selectFilterData(''); valueId.value = nodeData[props.objMap.value] || '';
defaultExpandedKey.value = [];
proxy.$refs.treeSelect.blur();
selectFilterData('');
}
} }
/** /**

View File

@@ -361,8 +361,8 @@
<script setup lang="ts" name="BasicStudent"> <script setup lang="ts" name="BasicStudent">
import { ref, reactive, defineAsyncComponent, computed, onMounted } from 'vue' import { ref, reactive, defineAsyncComponent, computed, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table"; import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList } from "/@/api/basic/basicstudentinfo";
import { import {
fetchList,
delObj, delObj,
exportStudentData, exportStudentData,
applyInternship, applyInternship,
@@ -477,63 +477,27 @@ const handleSelectionChange = (selection: any[]) => {
// 学生信息导出 // 学生信息导出
const handleExportStudent = async () => { const handleExportStudent = async () => {
try { useMessage().warning('功能开发中')
await exportStudentData(searchForm)
useMessage().success('导出成功')
} catch (err: any) {
useMessage().error(err.msg || '导出失败')
}
} }
// 申请顶岗 // 申请顶岗
const handleApplyInternship = async () => { const handleApplyInternship = async () => {
if (selectedRows.value.length === 0) { useMessage().warning('功能开发中')
useMessage().warning('请先选择学生')
return
}
try {
const stuNos = selectedRows.value.map((row: any) => row.stuNo)
await applyInternship({ stuNos })
useMessage().success('申请成功')
getDataList()
} catch (err: any) {
useMessage().error(err.msg || '申请失败')
}
} }
// 导出头像 // 导出头像
const handleExportAvatar = async () => { const handleExportAvatar = async () => {
try { useMessage().warning('功能开发中')
const params: any = { ...searchForm }
if (selectedRows.value.length > 0) {
params.stuNos = selectedRows.value.map((row: any) => row.stuNo)
}
await getDownPic(params)
useMessage().success('导出成功')
} catch (err: any) {
useMessage().error(err.msg || '导出失败')
}
} }
// 批量打印 // 批量打印
const handleBatchPrint = async () => { const handleBatchPrint = async () => {
if (selectedRows.value.length === 0) { useMessage().warning('功能开发中')
useMessage().warning('请先选择学生')
return
}
try {
const stuNos = selectedRows.value.map((row: any) => row.stuNo)
await preBatchPrint({ stuNos })
useMessage().success('打印准备成功')
} catch (err: any) {
useMessage().error(err.msg || '打印准备失败')
}
} }
// 段段清证书导入 // 段段清证书导入
const handleImportCertificate = () => { const handleImportCertificate = () => {
importCertificateDialogVisible.value = true useMessage().warning('功能开发中')
fileList.value = []
} }
// 上传相关 // 上传相关
@@ -579,111 +543,47 @@ const handleUploadError = (err: any) => {
// 学籍卡导出 // 学籍卡导出
const handleExportStudentCard = async () => { const handleExportStudentCard = async () => {
try { useMessage().warning('功能开发中')
const params: any = { ...searchForm }
if (selectedRows.value.length > 0) {
params.stuNos = selectedRows.value.map((row: any) => row.stuNo)
}
await exportStuInfoCard(params)
useMessage().success('导出成功')
} catch (err: any) {
useMessage().error(err.msg || '导出失败')
}
} }
// 证书导出 // 证书导出
const handleExportCertificate = async () => { const handleExportCertificate = async () => {
try { useMessage().warning('功能开发中')
const params: any = { ...searchForm }
if (selectedRows.value.length > 0) {
params.stuNos = selectedRows.value.map((row: any) => row.stuNo)
}
await exportCertificate(params)
useMessage().success('导出成功')
} catch (err: any) {
useMessage().error(err.msg || '导出失败')
}
} }
// 简单信息维护 // 简单信息维护
const handleSimpleEdit = (row: any) => { const handleSimpleEdit = (row: any) => {
if (simpleEditDialogRef.value) { useMessage().warning('功能开发中')
simpleEditDialogRef.value.openDialog(row)
}
} }
// 查看详情 // 查看详情
const handleViewDetail = (row: any) => { const handleViewDetail = (row: any) => {
if (detailDialogRef.value) { useMessage().warning('功能开发中')
detailDialogRef.value.openDialog(row.id)
}
} }
// 打印证件照 // 打印证件照
const handlePrintPhoto = async (row: any) => { const handlePrintPhoto = async (row: any) => {
try { useMessage().warning('功能开发中')
await prePrint(row.stuNo)
useMessage().success('打印准备成功')
} catch (err: any) {
useMessage().error(err.msg || '打印准备失败')
}
} }
// 重置密码 // 重置密码
const handleResetPassword = async (row: any) => { const handleResetPassword = async (row: any) => {
try { useMessage().warning('功能开发中')
await useMessageBox().confirm('确定要重置该学生的密码吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
await resetPassWord({ stuNo: row.stuNo })
useMessage().success('重置成功')
} catch (err: any) {
if (err !== 'cancel') {
useMessage().error(err.msg || '重置失败')
}
}
} }
// 设为班干部 // 设为班干部
const handleSetLeader = async (row: any) => { const handleSetLeader = async (row: any) => {
try { useMessage().warning('功能开发中')
await editIsleader({ id: row.id, isClassLeader: 1 })
useMessage().success('设置成功')
getDataList()
} catch (err: any) {
useMessage().error(err.msg || '设置失败')
}
} }
// 取消班干部 // 取消班干部
const handleCancelLeader = async (row: any) => { const handleCancelLeader = async (row: any) => {
try { useMessage().warning('功能开发中')
await editIsleader({ id: row.id, isClassLeader: 0 })
useMessage().success('取消成功')
getDataList()
} catch (err: any) {
useMessage().error(err.msg || '取消失败')
}
} }
// 禁止进出 // 禁止进出
const handleForbidInout = async (row: any) => { const handleForbidInout = async (row: any) => {
try { useMessage().warning('功能开发中')
await useMessageBox().confirm('确定要禁止该学生进出吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
await updateInout({ id: row.id, isAllowInout: 0 })
useMessage().success('操作成功')
getDataList()
} catch (err: any) {
if (err !== 'cancel') {
useMessage().error(err.msg || '操作失败')
}
}
} }
// 获取学院列表 // 获取学院列表

View File

@@ -53,9 +53,9 @@
<el-table-column prop="headImg" label="头像" width="120" align="center"> <el-table-column prop="headImg" label="头像" width="120" align="center">
<template #default="scope"> <template #default="scope">
<el-image <el-image
v-if="scope.row.headImg" v-if="scope.row.headImg || scope.row.imageUrl || scope.row.qrCode"
:src="scope.row.headImg" :src="scope.row.headImg || scope.row.imageUrl || scope.row.qrCode"
:preview-src-list="[scope.row.headImg]" :preview-src-list="[scope.row.headImg || scope.row.imageUrl || scope.row.qrCode]"
fit="cover" fit="cover"
style="width: 80px; height: 100px; cursor: pointer;" style="width: 80px; height: 100px; cursor: pointer;"
lazy> lazy>
@@ -96,10 +96,44 @@ const searchForm = reactive({
classCode: '' classCode: ''
}) })
// 配置 useTable // 配置 useTable - 接口返回的数据结构是 { classes: [], students: [] }
const state: BasicTableProps = reactive<BasicTableProps>({ const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm, queryForm: searchForm,
pageList: fetchList, pageList: async (queryParams: any) => {
const res = await fetchList(queryParams)
// 接口返回的数据结构是 { classes: [], students: [] }
// 需要将 students 数组转换为表格数据,并关联班级信息
if (res.data && res.data.students) {
const students = res.data.students || []
const classes = res.data.classes || []
const classMap = new Map()
classes.forEach((cls: any) => {
classMap.set(cls.classCode, cls)
})
// 将学生数据与班级信息合并
const dataList = students.map((stu: any) => {
const classInfo = classMap.get(stu.classCode)
return {
...stu,
className: classInfo ? classInfo.classNo : stu.className || '',
classNo: classInfo ? classInfo.classNo : ''
}
})
return {
...res,
data: {
records: dataList,
total: dataList.length,
current: 1,
size: dataList.length,
pages: 1
}
}
}
return res
},
props: { props: {
item: 'records', item: 'records',
totalCount: 'total' totalCount: 'total'

View File

@@ -53,7 +53,7 @@
{{ getPlanName(scope.row.groupId) }} {{ getPlanName(scope.row.groupId) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="zymc" label="专业名称" align="center" show-overflow-tooltip /> <el-table-column prop="majorName" label="专业名称" align="center" show-overflow-tooltip />
<el-table-column prop="wlx" label="未联系" align="center" show-overflow-tooltip /> <el-table-column prop="wlx" label="未联系" align="center" show-overflow-tooltip />
<el-table-column prop="yjbd" label="已经报到" align="center" show-overflow-tooltip /> <el-table-column prop="yjbd" label="已经报到" align="center" show-overflow-tooltip />
<el-table-column prop="tcbd" label="推迟报到" align="center" show-overflow-tooltip /> <el-table-column prop="tcbd" label="推迟报到" align="center" show-overflow-tooltip />

View File

@@ -44,9 +44,9 @@
<el-select v-model="queryForm.confirmedMajor" filterable clearable placeholder="请选择录取专业"> <el-select v-model="queryForm.confirmedMajor" filterable clearable placeholder="请选择录取专业">
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc + '(' + item.xz + '年制)'" :label="item.majorName + '(' + item.learnYear + '年制)'"
:value="item.zydm" :value="item.majorCode"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -239,11 +239,11 @@ import { useMessage, useMessageBox } from '/@/hooks/message'
import { list } from '/@/api/recruit/recruitstudentplangroup' import { list } from '/@/api/recruit/recruitstudentplangroup'
import { backPush, backSchoolStuPage, batchPushAll } from '/@/api/recruit/recruitstudentsignup' import { backPush, backSchoolStuPage, batchPushAll } from '/@/api/recruit/recruitstudentsignup'
import { getDeptList } from '/@/api/basic/basicclass' import { getDeptList } from '/@/api/basic/basicclass'
import { list as planMajor } from '/@/api/recruit/recruitplanmajor' import { listPlanByCondition as planMajor } from '/@/api/recruit/recruitstudentplan'
import { updateFs, updateAllFS } from '/@/api/finance/financenormalstu' import { updateFs, updateAllFS } from '/@/api/finance/financenormalstu'
import { getTypeValue } from '/@/api/admin/dict' import { getTypeValue } from '/@/api/admin/dict'
// @ts-ignore // @ts-ignore
import global from '@/components/tools/commondict' import global from '@/components/tools/commondict.vue'
const StuCheckIn = defineAsyncComponent(() => import('./stu-check-in.vue')) const StuCheckIn = defineAsyncComponent(() => import('./stu-check-in.vue'))
@@ -311,8 +311,8 @@ const getDeptName = (deptCode: string) => {
// 获取专业名称 // 获取专业名称
const getMajorName = (majorCode: string) => { const getMajorName = (majorCode: string) => {
const item = planMajorList.value.find(item => item.zydm === majorCode) const item = planMajorList.value.find(item => item.majorCode === majorCode)
return item ? item.zymc : '' return item ? item.majorName : ''
} }
// 获取性别 // 获取性别

View File

@@ -40,10 +40,10 @@
<el-select v-model="dataForm.wishMajorOne" filterable placeholder="请选择拟报专业1" size="small" style="width: 100%"> <el-select v-model="dataForm.wishMajorOne" filterable placeholder="请选择拟报专业1" size="small" style="width: 100%">
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' | '+item.xz+'年 | '+item.zydm" :label="item.majorName+' | '+item.learnYear+'年 | '+item.majorCode"
:value="item.zydm" :value="item.majorCode"
:disabled="isDisable(item.zydm)" :disabled="isDisable(item.majorCode)"
> >
</el-option> </el-option>
</el-select> </el-select>
@@ -52,10 +52,10 @@
<el-select v-model="dataForm.wishMajorTwo" filterable placeholder="请选择拟报专业2" size="small" style="width: 100%"> <el-select v-model="dataForm.wishMajorTwo" filterable placeholder="请选择拟报专业2" size="small" style="width: 100%">
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' | '+item.xz+'年 | '+item.zydm" :label="item.majorName+' | '+item.learnYear+'年 | '+item.majorCode"
:value="item.zydm" :value="item.majorCode"
:disabled="isDisable(item.zydm)" :disabled="isDisable(item.majorCode)"
> >
</el-option> </el-option>
</el-select> </el-select>
@@ -64,10 +64,10 @@
<el-select v-model="dataForm.wishMajorThree" filterable placeholder="请选择拟报专业3" size="small" style="width: 100%"> <el-select v-model="dataForm.wishMajorThree" filterable placeholder="请选择拟报专业3" size="small" style="width: 100%">
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' | '+item.xz+'年 | '+item.zydm" :label="item.majorName+' | '+item.learnYear+'年 | '+item.majorCode"
:value="item.zydm" :value="item.majorCode"
:disabled="isDisable(item.zydm)" :disabled="isDisable(item.majorCode)"
> >
</el-option> </el-option>
</el-select> </el-select>
@@ -76,9 +76,9 @@
<el-select v-model="dataForm.confirmedMajor" filterable placeholder="请选择录取专业" size="small" style="width: 100%"> <el-select v-model="dataForm.confirmedMajor" filterable placeholder="请选择录取专业" size="small" style="width: 100%">
<el-option <el-option
v-for="item in planMajorEduList" v-for="item in planMajorEduList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' | '+item.xz+'年 | '+item.zydm" :label="item.majorName+' | '+item.learnYear+'年 | '+item.majorCode"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -99,7 +99,7 @@ import { ref, reactive, nextTick } from 'vue'
import { ElNotification } from 'element-plus' import { ElNotification } from 'element-plus'
import { addMNObj, getMNObj, putMNObj } from '@/api/recruit/recruitImitateAdjustBatch' import { addMNObj, getMNObj, putMNObj } from '@/api/recruit/recruitImitateAdjustBatch'
import { getList } from "@/api/recruit/recruitstudentsignup" import { getList } from "@/api/recruit/recruitstudentsignup"
import { list as planMajor, listByEdu } from "@/api/recruit/recruitplanmajor" import { listPlanByCondition as planMajor, listByEdu } from "@/api/recruit/recruitstudentplan"
// Emits // Emits
const emit = defineEmits<{ const emit = defineEmits<{
@@ -151,10 +151,10 @@ const dataRule = {
/** /**
* 判断拟报专业是否已经占用,占用不可选 * 判断拟报专业是否已经占用,占用不可选
*/ */
const isDisable = (zydm: string) => { const isDisable = (majorCode: string) => {
if (zydm == dataForm.wishMajorOne if (majorCode == dataForm.wishMajorOne
|| zydm == dataForm.wishMajorTwo || majorCode == dataForm.wishMajorTwo
|| zydm == dataForm.wishMajorThree || majorCode == dataForm.wishMajorThree
) { ) {
return true return true
} else { } else {
@@ -262,7 +262,7 @@ const dataFormSubmit = () => {
// 初始化方法 // 初始化方法
const init = (id: string | null, groupId: string, batchNo: string) => { const init = (id: string | null, groupId: string, batchNo: string) => {
dataForm.id = id || "" dataForm.id = id || null
dataForm.batchNo = batchNo dataForm.batchNo = batchNo
dataForm.groupId = groupId dataForm.groupId = groupId
visible.value = true visible.value = true

View File

@@ -110,7 +110,7 @@ const dataFormSubmit = () => {
// 初始化方法 // 初始化方法
const init = (id: string | null) => { const init = (id: string | null) => {
dataForm.id = id || "" dataForm.id = id || null
visible.value = true visible.value = true
canSubmit.value = true canSubmit.value = true
initData() initData()

View File

@@ -55,7 +55,7 @@
align="center" align="center"
label="拟报专业1"> label="拟报专业1">
<template #default="scope"> <template #default="scope">
{{global.getLabelValueByPropes2(planMajorList,scope.row.wishMajorOne,{'key':'zydm','value':'zymc'})}} {{global.getLabelValueByPropes2(planMajorList,scope.row.wishMajorOne,{'key':'majorCode','value':'majorName'})}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@@ -65,7 +65,7 @@
width="100px" width="100px"
label="拟报专业2"> label="拟报专业2">
<template #default="scope"> <template #default="scope">
{{global.getLabelValueByPropes2(planMajorList,scope.row.wishMajorTwo,{'key':'zydm','value':'zymc'})}} {{global.getLabelValueByPropes2(planMajorList,scope.row.wishMajorTwo,{'key':'majorCode','value':'majorName'})}}
</template> </template>
</el-table-column> </el-table-column>
@@ -76,7 +76,7 @@
width="100px" width="100px"
label="拟报专业3"> label="拟报专业3">
<template #default="scope"> <template #default="scope">
{{global.getLabelValueByPropes2(planMajorList,scope.row.wishMajorThree,{'key':'zydm','value':'zymc'})}} {{global.getLabelValueByPropes2(planMajorList,scope.row.wishMajorThree,{'key':'majorCode','value':'majorName'})}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@@ -85,7 +85,7 @@
align="center" align="center"
label="原录取专业"> label="原录取专业">
<template #default="scope"> <template #default="scope">
{{global.getLabelValueByPropes2(planMajorList,scope.row.oldConfirmedMajor,{'key':'zydm','value':'zymc'})}} {{global.getLabelValueByPropes2(planMajorList,scope.row.oldConfirmedMajor,{'key':'majorCode','value':'majorName'})}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@@ -94,7 +94,7 @@
align="center" align="center"
label="模拟录取专业"> label="模拟录取专业">
<template #default="scope"> <template #default="scope">
{{global.getLabelValueByPropes2(planMajorList,scope.row.confirmedMajor,{'key':'zydm','value':'zymc'})}} {{global.getLabelValueByPropes2(planMajorList,scope.row.confirmedMajor,{'key':'majorCode','value':'majorName'})}}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@@ -131,7 +131,7 @@ import { useUserInfo } from '/@/stores/userInfo'
import { useMessage, useMessageBox } from '/@/hooks/message' import { useMessage, useMessageBox } from '/@/hooks/message'
import { Plus, Edit, Delete } from '@element-plus/icons-vue' import { Plus, Edit, Delete } from '@element-plus/icons-vue'
import { getMNStuList, delMNObj } from '@/api/recruit/recruitImitateAdjustBatch' import { getMNStuList, delMNObj } from '@/api/recruit/recruitImitateAdjustBatch'
import { list as planMajor } from "@/api/recruit/recruitplanmajor" import { listPlanByCondition as planMajor } from "@/api/recruit/recruitstudentplan"
import { getTypeValue } from "@/api/admin/dict" import { getTypeValue } from "@/api/admin/dict"
// @ts-ignore // @ts-ignore
import global from '@/components/tools/commondict' import global from '@/components/tools/commondict'

View File

@@ -20,15 +20,15 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="专业代码" prop="zydm"> <el-form-item label="专业代码" prop="majorCode">
<el-input v-model="dataForm.zydm" placeholder="专业代码"></el-input> <el-input v-model="dataForm.majorCode" placeholder="专业代码"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="专业名称" prop="zymc"> <el-form-item label="专业名称" prop="majorName">
<el-input v-model="dataForm.zymc" placeholder="专业名称"></el-input> <el-input v-model="dataForm.majorName" placeholder="专业名称"></el-input>
</el-form-item>
<el-form-item label="专业规范名称" prop="zygfmc">
<el-input v-model="dataForm.zygfmc" placeholder="专业规范名称"></el-input>
</el-form-item> </el-form-item>
<!-- <el-form-item label="专业规范名称" prop="zygfmc">-->
<!-- <el-input v-model="dataForm.zygfmc" placeholder="专业规范名称"></el-input>-->
<!-- </el-form-item>-->
<el-form-item label="所属学院" prop="deptCode"> <el-form-item label="所属学院" prop="deptCode">
<el-select v-model="dataForm.deptCode" filterable placeholder="请选择"> <el-select v-model="dataForm.deptCode" filterable placeholder="请选择">
<el-option <el-option
@@ -39,8 +39,8 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="学制" prop="xz"> <el-form-item label="学制" prop="learnYear">
<el-select v-model="dataForm.xz" filterable placeholder="请选择学制"> <el-select v-model="dataForm.learnYear" filterable placeholder="请选择学制">
<el-option <el-option
v-for="item in majorYears" v-for="item in majorYears"
:key="item.value" :key="item.value"
@@ -49,8 +49,8 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="层次" prop="cc"> <el-form-item label="层次" prop="majorLevel">
<el-select v-model="dataForm.cc" filterable placeholder="请选择层次"> <el-select v-model="dataForm.majorLevel" filterable placeholder="请选择层次">
<el-option <el-option
v-for="item in ccList" v-for="item in ccList"
:key="item.label" :key="item.label"
@@ -74,8 +74,8 @@
<el-radio v-for="item in yes_no_type" :key="item.value" :label="item.value">{{ item.label }}</el-radio> <el-radio v-for="item in yes_no_type" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="正式专业代码" prop="offcialZydm"> <el-form-item label="正式专业代码" prop="stuworkMajorCode">
<el-select v-model="dataForm.offcialZydm" filterable placeholder="请选择正式专业代码"> <el-select v-model="dataForm.stuworkMajorCode" filterable placeholder="请选择正式专业代码">
<el-option <el-option
v-for="item in offcialZydmList" v-for="item in offcialZydmList"
:key="item.majorCode" :key="item.majorCode"
@@ -85,18 +85,18 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="市平台代码" prop="cityPlanId"> <!-- <el-form-item label="市平台代码" prop="cityPlanId">-->
<el-select v-model="dataForm.cityPlanId" filterable placeholder="请选择市平台代码"> <!-- <el-select v-model="dataForm.cityPlanId" filterable placeholder="请选择市平台代码">-->
<el-option <!-- <el-option-->
v-for="item in cityPlanIdList" <!-- v-for="item in cityPlanIdList"-->
:key="item.id" <!-- :key="item.id"-->
:label="item.schoolMajorName+' | '+item.educational" <!-- :label="item.schoolMajorName+' | '+item.educational"-->
:value="item.id" <!-- :value="item.id"-->
:disabled="isCityDisable(item.id)" <!-- :disabled="isCityDisable(item.id)"-->
> <!-- >-->
</el-option> <!-- </el-option>-->
</el-select> <!-- </el-select>-->
</el-form-item> <!-- </el-form-item>-->
<el-form-item label="排序" prop="sort"> <el-form-item label="排序" prop="sort">
<el-input-number :min="0" :max="999" v-model="dataForm.sort" placeholder="排序" <el-input-number :min="0" :max="999" v-model="dataForm.sort" placeholder="排序"
style="width: 100%"></el-input-number> style="width: 100%"></el-input-number>
@@ -119,7 +119,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, nextTick } from 'vue' import { ref, reactive, nextTick } from 'vue'
import { ElNotification } from 'element-plus' import { ElNotification } from 'element-plus'
import { addObj, getObj, putObj, getCityPlan } from '/@/api/recruit/recruitplanmajor' import { addObj, getObj, putObj } from '/@/api/recruit/recruitstudentplan'
import { getDeptList } from '/@/api/basic/basicclass' import { getDeptList } from '/@/api/basic/basicclass'
import { list } from '/@/api/recruit/recruitstudentplangroup' import { list } from '/@/api/recruit/recruitstudentplangroup'
import { getMajorNameList } from '/@/api/basic/major' import { getMajorNameList } from '/@/api/basic/major'
@@ -150,51 +150,42 @@ const majorYears = ref<any[]>([])
const dataForm = reactive({ const dataForm = reactive({
id: "", id: "",
groupId: "", groupId: "",
zydm: "", majorCode: "",
zymc: "", majorName: "",
zygfmc: "",
deptCode: "", deptCode: "",
xz: "", learnYear: "",
cc: "", majorLevel: "",
isZd: "0", isZd: "0",
isOrder: "0", isOrder: "0",
remarks: "", remarks: "",
offcialZydm: "", stuworkMajorCode: "",
isUnion: "0", isUnion: "0",
tuitionFee: 0, tuitionFee: 0,
cityPlanId: null as string | null,
cityPlanIds: [] as string[],
cityPlanName: "",
cityPlanYear: "",
sort: 0 sort: 0
}) })
const dataRule = { const dataRule = {
zydm: [ majorCode: [
{ required: true, message: '专业代码不能为空', trigger: 'blur' }, { required: true, message: '专业代码不能为空', trigger: 'blur' },
{ min: 1, max: 6, message: '专业代码长度不大于6个字符', trigger: 'blur' } { min: 1, max: 6, message: '专业代码长度不大于6个字符', trigger: 'blur' }
], ],
tuitionFee: [ tuitionFee: [
{ required: true, message: '学费不能为空', trigger: 'blur' } { required: true, message: '学费不能为空', trigger: 'blur' }
], ],
zymc: [ majorName: [
{ required: true, message: '专业名称不能为空', trigger: 'blur' }, { required: true, message: '专业名称不能为空', trigger: 'blur' },
{ min: 1, max: 200, message: '专业名称长度不大于200个字符', trigger: 'blur' } { min: 1, max: 200, message: '专业名称长度不大于200个字符', trigger: 'blur' }
], ],
zygfmc: [
{ required: true, message: '专业规范名称不能为空', trigger: 'blur' },
{ min: 1, max: 200, message: '专业规范名称长度不大于200个字符', trigger: 'blur' }
],
groupId: [ groupId: [
{ required: true, message: '招生计划不能为空', trigger: 'blur' } { required: true, message: '招生计划不能为空', trigger: 'blur' }
], ],
xz: [ learnYear: [
{ required: true, message: '学制不能为空', trigger: 'blur' } { required: true, message: '学制不能为空', trigger: 'blur' }
], ],
deptCode: [ deptCode: [
{ required: true, message: '学院不能为空', trigger: 'blur' } { required: true, message: '学院不能为空', trigger: 'blur' }
], ],
cc: [ majorLevel: [
{ required: true, message: '层次不能为空', trigger: 'blur' } { required: true, message: '层次不能为空', trigger: 'blur' }
], ],
isOrder: [ isOrder: [
@@ -230,7 +221,7 @@ const initData = () => {
list().then((data: any) => { list().then((data: any) => {
planList.value = data.data planList.value = data.data
if (!dataForm.id) { if (!dataForm.id) {
dataForm.groupId = planList.value[0]?.id || "" dataForm.groupId = planList.value[0]?.id || null
} }
}) })
getMajorNameList().then((data: any) => { getMajorNameList().then((data: any) => {
@@ -287,7 +278,7 @@ const dataFormSubmit = () => {
// 初始化方法 // 初始化方法
const init = (id: string | null) => { const init = (id: string | null) => {
dataForm.id = id || "" dataForm.id = id || null
visible.value = true visible.value = true
canSubmit.value = true canSubmit.value = true
initData() initData()
@@ -297,9 +288,9 @@ const init = (id: string | null) => {
getObj(dataForm.id).then((response: any) => { getObj(dataForm.id).then((response: any) => {
Object.assign(dataForm, response.data) Object.assign(dataForm, response.data)
// 获取市平台对应年份下的招生计划 // 获取市平台对应年份下的招生计划
getCityPlan({ id: dataForm.id }).then((data: any) => { // getCityPlan({ id: dataForm.id }).then((data: any) => {
cityPlanIdList.value = data.data // cityPlanIdList.value = data.data
}) // })
}) })
} }
}) })

View File

@@ -40,14 +40,14 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="专业序号" prop="zydm"> <el-form-item label="专业序号" prop="majorCode">
<el-input v-model="queryForm.zydm" placeholder="专业序号" /> <el-input v-model="queryForm.majorCode" placeholder="专业序号" />
</el-form-item> </el-form-item>
<el-form-item label="专业名称" prop="zymc"> <el-form-item label="专业名称" prop="majorName">
<el-input v-model="queryForm.zymc" placeholder="专业名称" /> <el-input v-model="queryForm.majorName" placeholder="专业名称" />
</el-form-item> </el-form-item>
<el-form-item label="学制" prop="xz"> <el-form-item label="学制" prop="learnYear">
<el-input v-model="queryForm.xz" placeholder="学制" /> <el-input v-model="queryForm.learnYear" placeholder="学制" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="getDataList">查询</el-button> <el-button type="primary" icon="Search" @click="getDataList">查询</el-button>
@@ -83,16 +83,16 @@
{{ getPlanName(scope.row.groupId) }} {{ getPlanName(scope.row.groupId) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="zydm" label="专业序号" align="center" show-overflow-tooltip /> <el-table-column prop="majorCode" label="专业序号" align="center" show-overflow-tooltip />
<el-table-column prop="zymc" label="专业名称" align="center" show-overflow-tooltip /> <el-table-column prop="majorName" label="专业名称" align="center" show-overflow-tooltip />
<!-- <el-table-column prop="zygfmc" label="专业规范名称" align="center" show-overflow-tooltip /> --> <!-- <el-table-column prop="zygfmc" label="专业规范名称" align="center" show-overflow-tooltip /> -->
<el-table-column prop="deptCode" label="学院" align="center" show-overflow-tooltip> <el-table-column prop="deptCode" label="学院" align="center" show-overflow-tooltip>
<template #default="scope"> <template #default="scope">
{{ getDeptName(scope.row.deptCode) }} {{ getDeptName(scope.row.deptCode) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="xz" label="学制" align="center" width="80" show-overflow-tooltip /> <el-table-column prop="learnYear" label="学制" align="center" width="80" show-overflow-tooltip />
<el-table-column prop="cc" label="层次" align="center" show-overflow-tooltip /> <el-table-column prop="majorLevel" label="层次" align="center" show-overflow-tooltip />
<el-table-column prop="isOrder" label="订单班" align="center" width="80" show-overflow-tooltip> <el-table-column prop="isOrder" label="订单班" align="center" width="80" show-overflow-tooltip>
<template #default="scope"> <template #default="scope">
{{ getYesNoLabel(scope.row.isOrder) }} {{ getYesNoLabel(scope.row.isOrder) }}
@@ -120,9 +120,9 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="offcialZydm" label="正式专业代码" align="center" show-overflow-tooltip> <el-table-column prop="stuworkMajorCode" label="正式专业代码" align="center" show-overflow-tooltip>
<template #default="scope"> <template #default="scope">
{{ getMajorCodeName(scope.row.offcialZydm) }} {{ getMajorCodeName(scope.row.stuworkMajorCode) }}
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column prop="cityPlanId" label="市平台招生计划" align="center" show-overflow-tooltip> <!-- <el-table-column prop="cityPlanId" label="市平台招生计划" align="center" show-overflow-tooltip>
@@ -138,7 +138,7 @@
type="primary" type="primary"
link link
icon="EditPen" icon="EditPen"
@click="addOrUpdateHandle(scope.row.id)" @click="addOrUpdateHandle(scope.row)"
> >
修改 修改
</el-button> </el-button>
@@ -176,7 +176,7 @@ import { BasicTableProps, useTable } from '/@/hooks/table'
import { useMessage, useMessageBox } from '/@/hooks/message' import { useMessage, useMessageBox } from '/@/hooks/message'
import { useDict } from '/@/hooks/dict' import { useDict } from '/@/hooks/dict'
import { list } from '/@/api/recruit/recruitstudentplangroup' import { list } from '/@/api/recruit/recruitstudentplangroup'
import { fetchList, putObj, delObj } from '/@/api/recruit/recruitplanmajor' import { fetchList, putObj, delObj,editQuickField } from '/@/api/recruit/recruitstudentplan'
import { getDeptList } from '/@/api/basic/basicclass' import { getDeptList } from '/@/api/basic/basicclass'
import { getMajorNameList } from '/@/api/basic/major' import { getMajorNameList } from '/@/api/basic/major'
@@ -216,9 +216,9 @@ const offcialZydmList = ref<any[]>([])
const queryForm = reactive({ const queryForm = reactive({
groupId: '', groupId: '',
deptCode: '', deptCode: '',
zydm: '', majorCode: '',
zymc: '', majorName: '',
xz: '' learnYear: ''
}) })
// 获取计划名称 // 获取计划名称
@@ -290,7 +290,7 @@ const init = async () => {
// 修改开关 // 修改开关
const changeSm = async (row: any) => { const changeSm = async (row: any) => {
try { try {
await putObj(row) await editQuickField(row)
message.success('修改成功') message.success('修改成功')
} catch (error: any) { } catch (error: any) {
message.error(error.msg || '修改失败') message.error(error.msg || '修改失败')
@@ -298,9 +298,9 @@ const changeSm = async (row: any) => {
} }
// 新增 / 修改 // 新增 / 修改
const addOrUpdateHandle = (id?: string) => { const addOrUpdateHandle = (row?: any) => {
nextTick(() => { nextTick(() => {
addOrUpdateRef.value?.init(id || null) addOrUpdateRef.value?.init(row.id || null)
}) })
} }
@@ -321,9 +321,9 @@ const resetQuery = () => {
searchFormRef.value?.resetFields() searchFormRef.value?.resetFields()
queryForm.groupId = '' queryForm.groupId = ''
queryForm.deptCode = '' queryForm.deptCode = ''
queryForm.zydm = '' queryForm.majorCode = ''
queryForm.zymc = '' queryForm.majorName = ''
queryForm.xz = '' queryForm.learnYear = ''
if (planList.value.length > 0) { if (planList.value.length > 0) {
queryForm.groupId = planList.value[0].id queryForm.groupId = planList.value[0].id
} }

View File

@@ -22,13 +22,13 @@
stripe stripe
v-loading="dataListLoading"> v-loading="dataListLoading">
<el-table-column <el-table-column
prop="zymc" prop="majorName"
header-align="center" header-align="center"
align="center" align="center"
label="专业" label="专业"
> >
<template #default="scope"> <template #default="scope">
<span>{{ scope.row.zymc+' || '+scope.row.zydm+' || '+scope.row.xz+' 年制'}}</span> <span>{{ scope.row.majorName+' || '+scope.row.majorCode+' || '+scope.row.learnYear+' 年制'}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@@ -111,8 +111,7 @@
import { ref, reactive } from 'vue' import { ref, reactive } from 'vue'
import { useMessage, useMessageBox } from '/@/hooks/message' import { useMessage, useMessageBox } from '/@/hooks/message'
import { ElNotification } from 'element-plus' import { ElNotification } from 'element-plus'
import { list, delObj } from '/@/api/recruit/recruitplanmajor' import { listPlanByCondition as list, delObj ,putObj} from '/@/api/recruit/recruitstudentplan'
import { putObj } from '/@/api/recruit/recruitstudentplan'
import { fetchSecondTree } from '/@/api/basic/basicdept' import { fetchSecondTree } from '/@/api/basic/basicdept'
import { getDicts } from "/@/api/admin/dict" import { getDicts } from "/@/api/admin/dict"

View File

@@ -68,7 +68,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -80,7 +80,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -92,7 +92,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -104,7 +104,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -116,7 +116,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -129,7 +129,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -142,7 +142,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -155,7 +155,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -168,7 +168,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -181,7 +181,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -194,7 +194,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -207,7 +207,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc" :label="item.majorName"
:value="item.id" :value="item.id"
:disabled="isDisable(item.id)" :disabled="isDisable(item.id)"
> >
@@ -386,7 +386,7 @@ const dataFormSubmit = () => {
// 初始化方法 // 初始化方法
const init = (id: string | null) => { const init = (id: string | null) => {
dataForm.id = id || "" dataForm.id = id || null
visible.value = true visible.value = true
canSubmit.value = true canSubmit.value = true

View File

@@ -71,7 +71,7 @@
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.id" :key="item.id"
:label="item.zymc + ' || ' + item.zydm" :label="item.majorName + ' || ' + item.majorCode"
:value="item.id" :value="item.id"
/> />
</el-select> </el-select>
@@ -196,7 +196,7 @@ import { useDict } from '/@/hooks/dict'
import { useMessage, useMessageBox } from '/@/hooks/message' import { useMessage, useMessageBox } from '/@/hooks/message'
import { delObj, fetchList, sureDJ } from '/@/api/recruit/recruitprestudent' import { delObj, fetchList, sureDJ } from '/@/api/recruit/recruitprestudent'
import { list } from '/@/api/recruit/recruitstudentplangroup' import { list } from '/@/api/recruit/recruitstudentplangroup'
import { listcz } from '/@/api/recruit/recruitplanmajor' import { listcz } from '/@/api/recruit/recruitstudentplan'
import { list as schoolListApi } from '/@/api/recruit/recruitstudentschool' import { list as schoolListApi } from '/@/api/recruit/recruitstudentschool'
import { getDeptListByLevelTwo } from '/@/api/basic/basicdept' import { getDeptListByLevelTwo } from '/@/api/basic/basicdept'
@@ -250,7 +250,7 @@ const queryForm = reactive({
// 获取专业名称 // 获取专业名称
const getMajorName = (majorId: string) => { const getMajorName = (majorId: string) => {
const item = planMajorList.value.find(item => item.id === majorId) const item = planMajorList.value.find(item => item.id === majorId)
return item ? item.zymc : '' return item ? item.majorName : ''
} }
// 获取学校名称 // 获取学校名称

View File

@@ -30,7 +30,7 @@
:cell-style="tableStyle.cellStyle" :cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle" :header-cell-style="tableStyle.headerCellStyle"
> >
<el-table-column prop="zymc" header-align="center" align="center" label="专业" /> <el-table-column prop="majorName" header-align="center" align="center" label="专业" />
<el-table-column prop="number" header-align="center" align="center" label="人数" /> <el-table-column prop="number" header-align="center" align="center" label="人数" />
<el-table-column prop="rate" header-align="center" align="center" label="占比" /> <el-table-column prop="rate" header-align="center" align="center" label="占比" />
</el-table> </el-table>

View File

@@ -78,7 +78,7 @@ const initData = () => {
list().then((data: any) => { list().then((data: any) => {
planList.value = data.data planList.value = data.data
if (!dataForm.id) { if (!dataForm.id) {
dataForm.groupId = planList.value[0]?.id || "" dataForm.groupId = planList.value[0]?.id || null
} }
}) })
} }
@@ -117,7 +117,7 @@ const dataFormSubmit = () => {
// 初始化方法 // 初始化方法
const init = (id: string | null) => { const init = (id: string | null) => {
dataForm.id = id || "" dataForm.id = id || null
visible.value = true visible.value = true
canSubmit.value = true canSubmit.value = true
initData() initData()

View File

@@ -40,7 +40,7 @@
:header-cell-style="tableStyle.headerCellStyle" :header-cell-style="tableStyle.headerCellStyle"
> >
<el-table-column type="index" label="序号" width="60" align="center" /> <el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="zydm" label="专业代码" align="center" show-overflow-tooltip /> <el-table-column prop="majorCode" label="专业代码" align="center" show-overflow-tooltip />
<el-table-column prop="xy" label="系部" align="center" show-overflow-tooltip /> <el-table-column prop="xy" label="系部" align="center" show-overflow-tooltip />
<el-table-column prop="needStudentNum" label="拟招人数(不限男女)和拟招男女生数互斥" align="center" show-overflow-tooltip /> <el-table-column prop="needStudentNum" label="拟招人数(不限男女)和拟招男女生数互斥" align="center" show-overflow-tooltip />
<el-table-column prop="needStudentBoyNum" label="拟招男生数" align="center" show-overflow-tooltip /> <el-table-column prop="needStudentBoyNum" label="拟招男生数" align="center" show-overflow-tooltip />
@@ -102,8 +102,8 @@
:rules="formRules" :rules="formRules"
label-width="180px" label-width="180px"
> >
<el-form-item label="专业代码" prop="zydm"> <el-form-item label="专业代码" prop="majorCode">
<el-input v-model="form.zydm" placeholder="请输入专业代码" clearable /> <el-input v-model="form.majorCode" placeholder="请输入专业代码" clearable />
</el-form-item> </el-form-item>
<el-form-item label="系部" prop="xy"> <el-form-item label="系部" prop="xy">
<el-input v-model="form.xy" placeholder="请输入系部" clearable /> <el-input v-model="form.xy" placeholder="请输入系部" clearable />
@@ -205,7 +205,7 @@ const queryForm = reactive({})
// 表单数据 // 表单数据
const form = reactive({ const form = reactive({
id: '', id: '',
zydm: '', majorCode: '',
xy: '', xy: '',
needStudentNum: undefined, needStudentNum: undefined,
needStudentBoyNum: undefined, needStudentBoyNum: undefined,

View File

@@ -131,7 +131,7 @@ const dataFormSubmit = () => {
// 初始化方法 // 初始化方法
const init = (id: string | null) => { const init = (id: string | null) => {
dataForm.id = id || "" dataForm.id = id || null
visible.value = true visible.value = true
canSubmit.value = true canSubmit.value = true
nextTick(() => { nextTick(() => {

View File

@@ -104,7 +104,7 @@ const initData = () => {
list().then((data: any) => { list().then((data: any) => {
planList.value = data.data planList.value = data.data
if (!dataForm.id) { if (!dataForm.id) {
dataForm.groupId = planList.value[0]?.id || "" dataForm.groupId = planList.value[0]?.id || null
} }
}) })
// 获取所有省 // 获取所有省
@@ -147,7 +147,7 @@ const dataFormSubmit = () => {
// 初始化方法 // 初始化方法
const init = (id: string | null) => { const init = (id: string | null) => {
dataForm.id = id || "" dataForm.id = id || null
visible.value = true visible.value = true
canSubmit.value = true canSubmit.value = true
initData() initData()

View File

@@ -329,9 +329,9 @@
<el-select v-model="dataForm.wishMajorOne" filterable clearable placeholder="" size="small" style="width: 100%" > <el-select v-model="dataForm.wishMajorOne" filterable clearable placeholder="" size="small" style="width: 100%" >
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc" :label="item.majorName"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -343,9 +343,9 @@
<el-select v-model="dataForm.wishMajorTwo" filterable clearable placeholder="" size="small" style="width: 100%" > <el-select v-model="dataForm.wishMajorTwo" filterable clearable placeholder="" size="small" style="width: 100%" >
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc" :label="item.majorName"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -357,9 +357,9 @@
<el-select v-model="dataForm.wishMajorThree" filterable clearable placeholder="" size="small" style="width: 100%" > <el-select v-model="dataForm.wishMajorThree" filterable clearable placeholder="" size="small" style="width: 100%" >
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc" :label="item.majorName"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -371,9 +371,9 @@
<el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="" size="small" style="width: 100%" :disabled="type==1 ? false : true" @change="changeM(dataForm.confirmedMajor)"> <el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="" size="small" style="width: 100%" :disabled="type==1 ? false : true" @change="changeM(dataForm.confirmedMajor)">
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' || '+item.xyNum" :label="item.majorName+' || '+item.xyNum"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -385,9 +385,9 @@
<el-select v-model="dataForm.twoMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.twoMajor)"> <el-select v-model="dataForm.twoMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.twoMajor)">
<el-option <el-option
v-for="item in twoMajorList" v-for="item in twoMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' || '+item.xyNum" :label="item.majorName+' || '+item.xyNum"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -395,9 +395,9 @@
<el-select v-model="dataForm.threeMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.threeMajor)"> <el-select v-model="dataForm.threeMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.threeMajor)">
<el-option <el-option
v-for="item in threeMajorList" v-for="item in threeMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' || '+item.xyNum" :label="item.majorName+' || '+item.xyNum"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -405,9 +405,9 @@
<el-select v-model="dataForm.fourMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.fourMajor)"> <el-select v-model="dataForm.fourMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.fourMajor)">
<el-option <el-option
v-for="item in fourMajorList" v-for="item in fourMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' || '+item.xyNum" :label="item.majorName+' || '+item.xyNum"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -415,9 +415,9 @@
<el-select v-model="dataForm.fiveMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.fiveMajor)"> <el-select v-model="dataForm.fiveMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.fiveMajor)">
<el-option <el-option
v-for="item in fiveMajorList" v-for="item in fiveMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' || '+item.xyNum" :label="item.majorName+' || '+item.xyNum"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -425,9 +425,9 @@
<el-select v-model="dataForm.sixMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.sixMajor)"> <el-select v-model="dataForm.sixMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.sixMajor)">
<el-option <el-option
v-for="item in sixMajorList" v-for="item in sixMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' || '+item.xyNum" :label="item.majorName+' || '+item.xyNum"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -435,9 +435,9 @@
<el-select v-model="dataForm.sevenMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.sevenMajor)"> <el-select v-model="dataForm.sevenMajor" filterable clearable placeholder="" size="small" style="width: 100%" @change="changeM(dataForm.sevenMajor)">
<el-option <el-option
v-for="item in sevenMajorList" v-for="item in sevenMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' || '+item.xyNum" :label="item.majorName+' || '+item.xyNum"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -587,7 +587,7 @@ import { getObj, putObj } from '@/api/recruit/recruitstudentsignup'
import { list as listByGroupId } from '@/api/recruit/recruitstudentschool' import { list as listByGroupId } from '@/api/recruit/recruitstudentschool'
import { getDeptList } from "@/api/basic/basicclass" import { getDeptList } from "@/api/basic/basicclass"
import { list } from "@/api/recruit/recruitstudentplangroup" import { list } from "@/api/recruit/recruitstudentplangroup"
import { listByEdu } from "@/api/recruit/recruitplanmajor" import { listByEdu } from "@/api/recruit/recruitstudentplan"
import { getDictByType } from "@/api/contract/contract" import { getDictByType } from "@/api/contract/contract"
import { areaList, areaSonList } from "@/api/recruit/recruitstudentschool" import { areaList, areaSonList } from "@/api/recruit/recruitstudentschool"
import { list as scoreList } from "@/api/recruit/recruitstudentplancorrectscoreconfig" import { list as scoreList } from "@/api/recruit/recruitstudentplancorrectscoreconfig"
@@ -802,7 +802,7 @@ const dataRule = {
// 初始化 // 初始化
const init = (id: string | null, typeParam: number) => { const init = (id: string | null, typeParam: number) => {
dataForm.id = id || "" dataForm.id = id || null
type.value = typeParam type.value = typeParam
visible.value = true visible.value = true
canSubmit.value = true canSubmit.value = true
@@ -880,17 +880,17 @@ const init = (id: string | null, typeParam: number) => {
} }
// 根据年制分组 // 根据年制分组
planMajorList.value.forEach((item: any) => { planMajorList.value.forEach((item: any) => {
if (item.xz == '2') { if (item.learnYear == '2') {
twoMajorList.value.push(item) twoMajorList.value.push(item)
} else if (item.xz == '3') { } else if (item.learnYear == '3') {
threeMajorList.value.push(item) threeMajorList.value.push(item)
} else if (item.xz == '4') { } else if (item.learnYear == '4') {
fourMajorList.value.push(item) fourMajorList.value.push(item)
} else if (item.xz == '5') { } else if (item.learnYear == '5') {
fiveMajorList.value.push(item) fiveMajorList.value.push(item)
} else if (item.xz == '6') { } else if (item.learnYear == '6') {
sixMajorList.value.push(item) sixMajorList.value.push(item)
} else if (item.xz == '7') { } else if (item.learnYear == '7') {
sevenMajorList.value.push(item) sevenMajorList.value.push(item)
} }
}) })
@@ -1022,17 +1022,17 @@ const changeEducation = () => {
} }
// 根据年制分组 // 根据年制分组
planMajorList.value.forEach((item: any) => { planMajorList.value.forEach((item: any) => {
if (item.xz == '2') { if (item.learnYear == '2') {
twoMajorList.value.push(item) twoMajorList.value.push(item)
} else if (item.xz == '3') { } else if (item.learnYear == '3') {
threeMajorList.value.push(item) threeMajorList.value.push(item)
} else if (item.xz == '4') { } else if (item.learnYear == '4') {
fourMajorList.value.push(item) fourMajorList.value.push(item)
} else if (item.xz == '5') { } else if (item.learnYear == '5') {
fiveMajorList.value.push(item) fiveMajorList.value.push(item)
} else if (item.xz == '6') { } else if (item.learnYear == '6') {
sixMajorList.value.push(item) sixMajorList.value.push(item)
} else if (item.xz == '7') { } else if (item.learnYear == '7') {
sevenMajorList.value.push(item) sevenMajorList.value.push(item)
} }
}) })
@@ -1096,13 +1096,13 @@ const gzAuditChange = () => {
if (type.value != 0 && (dataForm.confirmedMajor == undefined || dataForm.confirmedMajor == "")) { if (type.value != 0 && (dataForm.confirmedMajor == undefined || dataForm.confirmedMajor == "")) {
// 根据折算分匹配录取专业 // 根据折算分匹配录取专业
planMajorList.value.forEach((e: any) => { planMajorList.value.forEach((e: any) => {
if (e.zydm == dataForm.wishMajorOne && (parseFloat(e.xyNum) > 0)) { if (e.majorCode == dataForm.wishMajorOne && (parseFloat(e.xyNum) > 0)) {
dataForm.confirmedMajor = dataForm.wishMajorOne dataForm.confirmedMajor = dataForm.wishMajorOne
} }
}) })
if (dataForm.confirmedMajor) { if (dataForm.confirmedMajor) {
planMajorList.value.forEach((e: any) => { planMajorList.value.forEach((e: any) => {
if (e.zydm == dataForm.wishMajorTwo && (parseFloat(e.xyNum) > 0)) { if (e.majorCode == dataForm.wishMajorTwo && (parseFloat(e.xyNum) > 0)) {
dataForm.confirmedMajor = dataForm.wishMajorOne dataForm.confirmedMajor = dataForm.wishMajorOne
} }
}) })
@@ -1110,7 +1110,7 @@ const gzAuditChange = () => {
if (dataForm.confirmedMajor) { if (dataForm.confirmedMajor) {
planMajorList.value.forEach((e: any) => { planMajorList.value.forEach((e: any) => {
if (e.zydm == dataForm.wishMajorThree && (parseFloat(e.xyNum) > 0)) { if (e.majorCode == dataForm.wishMajorThree && (parseFloat(e.xyNum) > 0)) {
dataForm.confirmedMajor = dataForm.wishMajorOne dataForm.confirmedMajor = dataForm.wishMajorOne
} }
}) })
@@ -1130,13 +1130,13 @@ const jsZSF = () => {
dataForm.correctedScore = String(Math.floor(score / parseFloat(String(dataForm.fullScore)) + fjf)) dataForm.correctedScore = String(Math.floor(score / parseFloat(String(dataForm.fullScore)) + fjf))
// 根据折算分匹配录取专业 // 根据折算分匹配录取专业
planMajorList.value.forEach((e: any) => { planMajorList.value.forEach((e: any) => {
if (dataForm.correctedScore >= e.scoreLine && e.zydm == dataForm.wishMajorOne && (parseFloat(e.xyNum) > 0)) { if (dataForm.correctedScore >= e.scoreLine && e.majorCode == dataForm.wishMajorOne && (parseFloat(e.xyNum) > 0)) {
dataForm.confirmedMajor = dataForm.wishMajorOne dataForm.confirmedMajor = dataForm.wishMajorOne
} }
}) })
if (dataForm.confirmedMajor == "") { if (dataForm.confirmedMajor == "") {
planMajorList.value.forEach((e: any) => { planMajorList.value.forEach((e: any) => {
if (dataForm.correctedScore >= e.scoreLine && e.zydm == dataForm.wishMajorTwo && (parseFloat(e.xyNum) > 0)) { if (dataForm.correctedScore >= e.scoreLine && e.majorCode == dataForm.wishMajorTwo && (parseFloat(e.xyNum) > 0)) {
dataForm.confirmedMajor = dataForm.wishMajorTwo dataForm.confirmedMajor = dataForm.wishMajorTwo
} }
}) })
@@ -1144,7 +1144,7 @@ const jsZSF = () => {
if (dataForm.confirmedMajor == "") { if (dataForm.confirmedMajor == "") {
planMajorList.value.forEach((e: any) => { planMajorList.value.forEach((e: any) => {
if (dataForm.correctedScore >= e.scoreLine && e.zydm == dataForm.wishMajorThree && (parseFloat(e.xyNum) > 0)) { if (dataForm.correctedScore >= e.scoreLine && e.majorCode == dataForm.wishMajorThree && (parseFloat(e.xyNum) > 0)) {
dataForm.confirmedMajor = dataForm.wishMajorThree dataForm.confirmedMajor = dataForm.wishMajorThree
} }
}) })
@@ -1201,7 +1201,7 @@ const changeM = (id: string) => {
dataForm.confirmedMajor = id dataForm.confirmedMajor = id
// 是初中生并且是中德班 // 是初中生并且是中德班
planMajorList.value.forEach((e: any) => { planMajorList.value.forEach((e: any) => {
if (dataForm.confirmedMajor == e.zydm && e.isZd == "1" && dataForm.degreeOfEducation == "1") { if (dataForm.confirmedMajor == e.majorCode && e.isZd == "1" && dataForm.degreeOfEducation == "1") {
flag = true flag = true
} }
}) })

View File

@@ -70,9 +70,9 @@
<el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="请选择录取专业"> <el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="请选择录取专业">
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+'('+item.xz+'年制)'" :label="item.majorName+'('+item.learnYear+'年制)'"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -81,9 +81,9 @@
<el-select v-model="dataForm.wishMajorOne" filterable clearable placeholder="请选择录取专业"> <el-select v-model="dataForm.wishMajorOne" filterable clearable placeholder="请选择录取专业">
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+'('+item.xz+'年制)'" :label="item.majorName+'('+item.learnYear+'年制)'"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -423,7 +423,7 @@
<br/> <br/>
<div v-if="scope.row.auditStatus==20"> <div v-if="scope.row.auditStatus==20">
录取专业: 录取专业:
{{ getMajorLabelWithYears(planMajorList, scope.row.confirmedMajor, { key: 'zydm', value: 'zymc' }) }}<br/> {{ getMajorLabelWithYears(planMajorList, scope.row.confirmedMajor, { key: 'majorCode', value: 'majorName' }) }}<br/>
</div> </div>
<div v-if="scope.row.auditStatus==20"> <div v-if="scope.row.auditStatus==20">
录取时间:{{ dateFormat(scope.row.auditTime) }} 录取时间:{{ dateFormat(scope.row.auditTime) }}
@@ -539,11 +539,11 @@ import {
pushCity as pushCityApi pushCity as pushCityApi
} from '/@/api/recruit/recruitstudentsignup' } from '/@/api/recruit/recruitstudentsignup'
import { getLabelValue, getLabelValueByProps, getMajorLabelWithYears } from '/@/utils/dictLabel' import { getLabelValue, getLabelValueByProps, getMajorLabelWithYears } from '/@/utils/dictLabel'
import { getDeptList } from '/@/api/basic/basicclass' import {getDeptList} from "/@/api/basic/basicclass";
import { list as planMajor } from '/@/api/recruit/recruitplanmajor' import {listPlanByCondition as planMajor} from "/@/api/recruit/recruitstudentplan";
import { getTypeValue, getDictsByTypes } from '/@/api/admin/dict' import {getTypeValue, getDictsByTypes} from "/@/api/admin/dict";
import { getUserListByRole } from '/@/api/admin/user' import {getUserListByRole} from "/@/api/admin/user";
import { queryTeacherBaseByNo } from '/@/api/professional/professionaluser/teacherbase' import {queryTeacherBaseByNo} from "/@/api/professional/professionaluser/teacherbase";
// ROLE_CODE 常量定义 // ROLE_CODE 常量定义
const ROLE_CODE = { const ROLE_CODE = {

View File

@@ -34,9 +34,9 @@
<el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="请选择录取专业" size="small" > <el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="请选择录取专业" size="small" >
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+'('+item.xz+'年制)'" :label="item.majorName+'('+item.learnYear+'年制)'"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -45,9 +45,9 @@
<el-select v-model="dataForm.wishMajorOne" filterable clearable placeholder="请选择录取专业" size="small" > <el-select v-model="dataForm.wishMajorOne" filterable clearable placeholder="请选择录取专业" size="small" >
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+'('+item.xz+'年制)'" :label="item.majorName+'('+item.learnYear+'年制)'"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -245,7 +245,7 @@
align="center" align="center"
label="录取专业"> label="录取专业">
<template #default="scope" > <template #default="scope" >
<span v-if="scope.row.auditStatus==20">{{getLabelValueByPropes2(planMajorList,scope.row.confirmedMajor,{'key':'zydm','value':'zymc'})}}</span> <span v-if="scope.row.auditStatus==20">{{getLabelValueByPropes2(planMajorList,scope.row.confirmedMajor,{'key':'majorCode','value':'majorName'})}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@@ -447,7 +447,7 @@ import {
} from '@/api/recruit/recruitstudentsignup' } from '@/api/recruit/recruitstudentsignup'
import global from '@/components/tools/commondict' import global from '@/components/tools/commondict'
import { getClassListByRole, getDeptList, queryAllClassByInfo } from "@/api/basic/basicclass" import { getClassListByRole, getDeptList, queryAllClassByInfo } from "@/api/basic/basicclass"
import { list as planMajor } from "@/api/recruit/recruitplanmajor" import {listPlanByCondition as planMajor} from "@/api/recruit/recruitstudentplan"
import { getTypeValue } from "@/api/admin/dict" import { getTypeValue } from "@/api/admin/dict"
import { getUserListByRole } from "@/api/admin/user" import { getUserListByRole } from "@/api/admin/user"
import { ROLE_CODE } from "@/config/global" import { ROLE_CODE } from "@/config/global"

View File

@@ -12,8 +12,8 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="学制" prop="xz"> <el-form-item label="学制" prop="learnYear">
<el-select v-model="queryForm.xz" filterable placeholder="请选择学制" clearable> <el-select v-model="queryForm.learnYear" filterable placeholder="请选择学制" clearable>
<el-option <el-option
v-for="item in majorYears" v-for="item in majorYears"
:key="item.value" :key="item.value"
@@ -57,7 +57,7 @@
{{ getDeptType(scope.row.deptCode) }} {{ getDeptType(scope.row.deptCode) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="zymc" header-align="center" align="center" label="所报专业" /> <el-table-column prop="majorName" header-align="center" align="center" label="所报专业" />
<el-table-column prop="maxScore" header-align="center" align="center" label="最高分" /> <el-table-column prop="maxScore" header-align="center" align="center" label="最高分" />
<el-table-column prop="minScore" header-align="center" align="center" label="最低分" /> <el-table-column prop="minScore" header-align="center" align="center" label="最低分" />
<el-table-column prop="avgScore" header-align="center" align="center" label="平均分" /> <el-table-column prop="avgScore" header-align="center" align="center" label="平均分" />
@@ -97,7 +97,7 @@ const exportLoading = ref(false)
// 查询表单 // 查询表单
const queryForm = reactive({ const queryForm = reactive({
groupId: '', groupId: '',
xz: '', learnYear: '',
isUnion: '' isUnion: ''
}) })
@@ -154,7 +154,7 @@ const dataExportHandle = async () => {
// 改变行颜色 // 改变行颜色
const changeRowColor = ({ row }: { row: any }) => { const changeRowColor = ({ row }: { row: any }) => {
if (row.zymc === '合计') { if (row.majorName === '合计') {
return { return {
color: 'red' color: 'red'
} }
@@ -178,7 +178,7 @@ const resetQuery = () => {
if (planList.value.length > 0) { if (planList.value.length > 0) {
queryForm.groupId = planList.value[0].id queryForm.groupId = planList.value[0].id
} }
queryForm.xz = '' queryForm.learnYear = ''
queryForm.isUnion = '' queryForm.isUnion = ''
getDataList() getDataList()
} }

View File

@@ -44,9 +44,9 @@
<el-select v-model="queryForm.confirmedMajor" filterable clearable placeholder="请选择录取专业"> <el-select v-model="queryForm.confirmedMajor" filterable clearable placeholder="请选择录取专业">
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc + '(' + item.xz + '年制)'" :label="item.majorName + '(' + item.learnYear + '年制)'"
:value="item.zydm" :value="item.majorCode"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -268,7 +268,6 @@ import { useMessage, useMessageBox } from '/@/hooks/message'
import { list } from '/@/api/recruit/recruitstudentplangroup' import { list } from '/@/api/recruit/recruitstudentplangroup'
import { fetchListStuDorm, yjOut, setFw, delFw, yjSend } from '/@/api/recruit/recruitstudentsignup' import { fetchListStuDorm, yjOut, setFw, delFw, yjSend } from '/@/api/recruit/recruitstudentsignup'
import { getDeptList } from '/@/api/basic/basicclass' import { getDeptList } from '/@/api/basic/basicclass'
import { list as planMajor } from '/@/api/recruit/recruitplanmajor'
// @ts-ignore // @ts-ignore
import global from '@/components/tools/commondict' import global from '@/components/tools/commondict'

View File

@@ -49,9 +49,9 @@
<el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="" size="small" style="width: 100%" :disabled="type != 1" @change="changeM(dataForm.confirmedMajor)"> <el-select v-model="dataForm.confirmedMajor" filterable clearable placeholder="" size="small" style="width: 100%" :disabled="type != 1" @change="changeM(dataForm.confirmedMajor)">
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc" :label="item.majorName"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -63,9 +63,9 @@
<el-select v-model="dataForm.newConfirmedMajor" filterable placeholder="" size="small" style="width: 100%" @change="changeCM(dataForm.newConfirmedMajor)"> <el-select v-model="dataForm.newConfirmedMajor" filterable placeholder="" size="small" style="width: 100%" @change="changeCM(dataForm.newConfirmedMajor)">
<el-option <el-option
v-for="item in planMajorList" v-for="item in planMajorList"
:key="item.zydm" :key="item.majorCode"
:label="item.zymc+' || '+item.xyNum" :label="item.majorName+' || '+item.xyNum"
:value="item.zydm"> :value="item.majorCode">
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -113,7 +113,7 @@ import { ElNotification } from 'element-plus'
import { useMessageBox } from '/@/hooks/message' import { useMessageBox } from '/@/hooks/message'
import { getObj, changeMajor } from '@/api/recruit/recruitstudentsignup' import { getObj, changeMajor } from '@/api/recruit/recruitstudentsignup'
import { list } from "@/api/recruit/recruitstudentplangroup" import { list } from "@/api/recruit/recruitstudentplangroup"
import { listByEdu } from "@/api/recruit/recruitplanmajor" import { listByEdu } from "@/api/recruit/recruitstudentplan"
import { getDictByType } from "@/api/contract/contract" import { getDictByType } from "@/api/contract/contract"
import { list as scoreList } from "@/api/recruit/recruitstudentplancorrectscoreconfig" import { list as scoreList } from "@/api/recruit/recruitstudentplancorrectscoreconfig"
@@ -242,7 +242,7 @@ const changeCM = (id: string) => {
if (id) { if (id) {
let flag = false let flag = false
planMajorList.value.forEach((e: any) => { planMajorList.value.forEach((e: any) => {
if (dataForm.newConfirmedMajor == e.zydm && e.isZd == "1" && String(dataForm.degreeOfEducation) == "1") { if (dataForm.newConfirmedMajor == e.majorCode && e.isZd == "1" && String(dataForm.degreeOfEducation) == "1") {
flag = true flag = true
} }
}) })
@@ -264,7 +264,7 @@ const changeM = (id: string) => {
// 是初中生并且是中德班 // 是初中生并且是中德班
let flag = false let flag = false
planMajorList.value.forEach((e: any) => { planMajorList.value.forEach((e: any) => {
if (dataForm.confirmedMajor == e.zydm && e.isZd == "1" && String(dataForm.degreeOfEducation) == "1") { if (dataForm.confirmedMajor == e.majorCode && e.isZd == "1" && String(dataForm.degreeOfEducation) == "1") {
flag = true flag = true
} }
}) })
@@ -315,7 +315,7 @@ const dataFormSubmit = async () => {
// 初始化方法 // 初始化方法
const init = (id: string | null) => { const init = (id: string | null) => {
dataForm.id = id || "" dataForm.id = id || null
visible.value = true visible.value = true
canSubmit.value = true canSubmit.value = true
initData() initData()

View File

@@ -36,8 +36,8 @@
{{ global.getLabelValueByPropes(deptList, scope.row.deptCode, { key: 'deptCode', value: 'deptName' }) }} {{ global.getLabelValueByPropes(deptList, scope.row.deptCode, { key: 'deptCode', value: 'deptName' }) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column width="150" prop="zydm" header-align="center" align="center" label="专业代码" /> <el-table-column width="150" prop="majorCode" header-align="center" align="center" label="专业代码" />
<el-table-column prop="zymc" header-align="center" align="center" label="专业名称" /> <el-table-column prop="majorName" header-align="center" align="center" label="专业名称" />
<el-table-column width="80" prop="scoreLine" header-align="center" align="center" label="分数线" /> <el-table-column width="80" prop="scoreLine" header-align="center" align="center" label="分数线" />
<el-table-column width="80" prop="planNum" header-align="center" align="center" label="计划总数" /> <el-table-column width="80" prop="planNum" header-align="center" align="center" label="计划总数" />
<el-table-column width="80" prop="recruitmentNum" header-align="center" align="center" label="拟招人数" /> <el-table-column width="80" prop="recruitmentNum" header-align="center" align="center" label="拟招人数" />
@@ -58,7 +58,7 @@ import { BasicTableProps, useTable } from '/@/hooks/table'
import { useMessage } from '/@/hooks/message' import { useMessage } from '/@/hooks/message'
import { useDict } from '/@/hooks/dict' import { useDict } from '/@/hooks/dict'
import { list } from '/@/api/recruit/recruitstudentplangroup' import { list } from '/@/api/recruit/recruitstudentplangroup'
import { fetchListByStatic, list as planMajor } from '/@/api/recruit/recruitplanmajor' import { fetchListByStatic, listPlanByCondition as planMajor } from '/@/api/recruit/recruitstudentplan'
import { getDeptList } from '/@/api/basic/basicclass' import { getDeptList } from '/@/api/basic/basicclass'
// @ts-ignore // @ts-ignore
import global from '/@/components/tools/commondict.vue' import global from '/@/components/tools/commondict.vue'
@@ -135,7 +135,7 @@ const init = async () => {
const handleExport = async () => { const handleExport = async () => {
try { try {
exportLoading.value = true exportLoading.value = true
await downBlobFile('/recruit/recruitplanmajor/exportExcel', queryForm, '招生统计.xls') await downBlobFile('/recruit/recruitstudentsignup/exportExcel', queryForm, '招生统计.xls')
} catch (error: any) { } catch (error: any) {
message.error(error.msg || '导出失败') message.error(error.msg || '导出失败')
} finally { } finally {

View File

@@ -563,7 +563,7 @@ const dataFormSubmit = (submitType: string) => {
// 初始化方法 // 初始化方法
const init = (id: string | null) => { const init = (id: string | null) => {
dataForm.id = id || "" dataForm.id = id || null
visible.value = true visible.value = true
canSubmit.value = true canSubmit.value = true
initData() initData()

View File

@@ -29,21 +29,6 @@
clearable clearable
style="width: 200px" /> style="width: 200px" />
</el-form-item> </el-form-item>
<el-form-item label="班号" prop="classCode">
<el-select
v-model="searchForm.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-form-item>
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</el-button> <el-button type="primary" plain icon="Search" @click="handleSearch">查询</el-button>
<el-button icon="Refresh" @click="handleReset">重置</el-button> <el-button icon="Refresh" @click="handleReset">重置</el-button>
@@ -166,7 +151,6 @@ import { ref, reactive, defineAsyncComponent, onMounted, computed } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table"; import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList } from "/@/api/stuwork/classhygienedailyanalysis"; import { fetchList } from "/@/api/stuwork/classhygienedailyanalysis";
import { useMessage } from "/@/hooks/message"; import { useMessage } from "/@/hooks/message";
import { getClassListByRole } from '/@/api/basic/basicclass'
import { getBuildingList } from '/@/api/stuwork/dormbuilding' import { getBuildingList } from '/@/api/stuwork/dormbuilding'
// 定义变量内容 // 定义变量内容
@@ -174,7 +158,6 @@ const searchFormRef = ref()
const scoreFormRef = ref() const scoreFormRef = ref()
// 搜索变量 // 搜索变量
const showSearch = ref(true) const showSearch = ref(true)
const classList = ref<any[]>([])
const buildingList = ref<any[]>([]) const buildingList = ref<any[]>([])
const scoreDialogVisible = ref(false) const scoreDialogVisible = ref(false)
const scoreDialogTitle = ref('加分') const scoreDialogTitle = ref('加分')
@@ -192,8 +175,7 @@ const scoreForm = reactive({
// 搜索表单 // 搜索表单
const searchForm = reactive({ const searchForm = reactive({
buildingNo: '', buildingNo: '',
month: '', month: ''
classCode: ''
}) })
// 计算月份的天数列 // 计算月份的天数列
@@ -206,31 +188,77 @@ const dayColumns = computed(() => {
return Array.from({ length: daysInMonth }, (_, i) => i + 1) return Array.from({ length: daysInMonth }, (_, i) => i + 1)
}) })
// 配置 useTable - 需要将月份转换为开始和结束时间,且不传分页参数 // 配置 useTable - 接口参数为 buildingNo 和 month数组格式
const state: BasicTableProps = reactive<BasicTableProps>({ const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm, queryForm: searchForm,
isPage: false, // 接口不支持分页
pageList: async (queryParams: any) => { pageList: async (queryParams: any) => {
// 如果选择了月份,转换为开始和结束时间
const params: any = {} const params: any = {}
// 如果选择了月份,转换为开始和结束时间 // 接口文档要求 buildingNo 和 month 都是数组格式
if (searchForm.buildingNo) {
params.buildingNo = Array.isArray(searchForm.buildingNo) ? searchForm.buildingNo : [searchForm.buildingNo]
}
if (searchForm.month) { if (searchForm.month) {
const [year, month] = searchForm.month.split('-').map(Number) params.month = Array.isArray(searchForm.month) ? searchForm.month : [searchForm.month]
const daysInMonth = new Date(year, month, 0).getDate()
params.startTime = `${year}-${String(month).padStart(2, '0')}-01`
params.endTime = `${year}-${String(month).padStart(2, '0')}-${String(daysInMonth).padStart(2, '0')}`
} }
// 如果选择了班号转换为数组格式接口要求classCode是数组 const res = await fetchList(params)
if (searchForm.classCode) {
params.classCode = Array.isArray(searchForm.classCode) ? searchForm.classCode : [searchForm.classCode] // 接口返回的数据结构:数组,每个元素包含日期字段(如 2025-12-01和班级信息
// 需要确保返回数组格式给 useTable
let dataList = []
if (Array.isArray(res.data)) {
dataList = res.data
} else if (res.data && Array.isArray(res.data.records)) {
dataList = res.data.records
} else if (res.data && Array.isArray(res.data.list)) {
dataList = res.data.list
} else if (res.data && typeof res.data === 'object') {
// 如果 res.data 是单个对象,转换为数组
dataList = [res.data]
} }
// 楼号参数 - 接口文档中没有buildingNo参数可能需要通过其他方式处理 // 处理数据:将日期字段转换为 day1, day2 等格式,方便表格显示
// 暂时不传递buildingNo如果需要可以后续添加 const processedData = dataList.map((item: any) => {
const processed: any = {
classCode: item.classCode || '',
classNo: item.classNo || '',
totalScore: item.scoreTotal || 0,
rank: item.order || 0,
isAddScore: item.isAddScore || 0
}
// 提取所有日期字段(格式为 YYYY-MM-DD
const datePattern = /^\d{4}-\d{2}-\d{2}$/
Object.keys(item).forEach(key => {
if (datePattern.test(key)) {
// 将日期转换为 day1, day2 等格式(根据日期中的天数)
const date = new Date(key)
const day = date.getDate()
processed[`day${day}`] = item[key]
}
})
// 确保所有日期字段都存在即使值为0或null避免表格列无法显示
if (searchForm.month) {
const [year, month] = searchForm.month.split('-').map(Number)
const daysInMonth = new Date(year, month, 0).getDate()
for (let i = 1; i <= daysInMonth; i++) {
if (!processed.hasOwnProperty(`day${i}`)) {
processed[`day${i}`] = 0
}
}
}
return processed
})
// 不传递分页参数current、size return {
return await fetchList(params) ...res,
data: processedData
}
}, },
props: { props: {
item: 'records', item: 'records',
@@ -262,7 +290,6 @@ const handleReset = () => {
searchFormRef.value?.resetFields() searchFormRef.value?.resetFields()
searchForm.buildingNo = '' searchForm.buildingNo = ''
searchForm.month = '' searchForm.month = ''
searchForm.classCode = ''
getDataList() getDataList()
} }
@@ -317,19 +344,6 @@ const submitScore = async () => {
} }
} }
// 获取班号列表
const getClassListData = async () => {
try {
const res = await getClassListByRole()
if (res.data) {
classList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取班号列表失败', err)
classList.value = []
}
}
// 获取楼号列表 // 获取楼号列表
const getBuildingListData = async () => { const getBuildingListData = async () => {
try { try {
@@ -352,7 +366,6 @@ const getBuildingListData = async () => {
// 初始化 // 初始化
onMounted(() => { onMounted(() => {
getClassListData()
getBuildingListData() getBuildingListData()
}) })
</script> </script>

View File

@@ -0,0 +1,182 @@
<template>
<el-dialog
:title="dialogTitle"
v-model="visible"
:width="1000"
:close-on-click-modal="false"
draggable>
<el-table
:data="tableData"
v-loading="loading"
border
style="width: 100%">
<!-- 空宿舍列表序号宿舍几人间是否有空调 -->
<template v-if="roomType === 'all'">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="roomNo" label="宿舍" show-overflow-tooltip align="center" />
<el-table-column prop="bedNum" label="几人间" show-overflow-tooltip align="center" />
<el-table-column prop="isHaveAir" label="是否有空调" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.isHaveAir === '1' || scope.row.isHaveAir === 1 ? '已安装' : '未安装' }}</span>
</template>
</el-table-column>
</template>
<!-- 空几人宿舍列表宿舍床位1-6是否有空调 -->
<template v-else>
<el-table-column prop="roomNo" label="宿舍" show-overflow-tooltip align="center" />
<el-table-column prop="bedNo1" label="床位1" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.bedNo1 || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="bedNo2" label="床位2" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.bedNo2 || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="bedNo3" label="床位3" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.bedNo3 || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="bedNo4" label="床位4" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.bedNo4 || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="bedNo5" label="床位5" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.bedNo5 || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="bedNo6" label="床位6" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.bedNo6 || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="isHaveAir" label="是否有空调" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.isHaveAir === '1' || scope.row.isHaveAir === 1 ? '已安装' : '未安装' }}</span>
</template>
</el-table-column>
</template>
</el-table>
<!-- 分页 -->
<pagination
v-if="isPage"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
v-bind="pagination" />
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts" name="EmptyRoomDialog">
import { ref, reactive, computed } from 'vue'
import { queryEmptyRoomWithBuildingNo, queryEmtryRoomDetail } from '/@/api/stuwork/dormroomstudent'
import { useMessage } from '/@/hooks/message'
// 定义变量内容
const visible = ref(false)
const loading = ref(false)
const buildingNo = ref('')
const roomType = ref('')
const tableData = ref<any[]>([])
const isPage = ref(false)
const pagination = reactive({
current: 1,
size: 10,
total: 0,
pageSizes: [10, 20, 50, 100],
layout: 'total, sizes, prev, pager, next, jumper'
})
// 对话框标题
const dialogTitle = computed(() => {
if (roomType.value === 'all') {
return `空宿舍列表 - ${buildingNo.value}号楼`
} else {
return `${roomType.value}人宿舍列表 - ${buildingNo.value}号楼`
}
})
// 打开对话框
const openDialog = async (building: string, type: string) => {
visible.value = true
buildingNo.value = building
roomType.value = type
tableData.value = []
pagination.current = 1
pagination.total = 0
await loadData()
}
// 加载数据
const loadData = async () => {
loading.value = true
try {
let res: any
if (roomType.value === 'all') {
// 查询所有空宿舍
res = await queryEmptyRoomWithBuildingNo(buildingNo.value)
} else {
// 查询空几人宿舍
res = await queryEmtryRoomDetail(buildingNo.value, roomType.value)
}
// 处理返回数据
if (res.data) {
if (Array.isArray(res.data)) {
tableData.value = res.data
isPage.value = false
} else if (res.data.records && Array.isArray(res.data.records)) {
tableData.value = res.data.records
pagination.total = res.data.total || 0
isPage.value = true
} else if (res.data.list && Array.isArray(res.data.list)) {
tableData.value = res.data.list
isPage.value = false
} else {
tableData.value = []
isPage.value = false
}
} else {
tableData.value = []
isPage.value = false
}
} catch (err: any) {
console.error('加载空宿舍列表失败', err)
useMessage().error(err.msg || '加载失败')
tableData.value = []
} finally {
loading.value = false
}
}
// 分页大小改变
const sizeChangeHandle = (val: number) => {
pagination.size = val
pagination.current = 1
loadData()
}
// 当前页改变
const currentChangeHandle = (val: number) => {
pagination.current = val
loadData()
}
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View File

@@ -0,0 +1,126 @@
<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-form-item label="楼号" prop="buildingNo">
<el-input v-model="form.buildingNo" placeholder="请输入楼号" />
</el-form-item>
<el-form-item label="层数" prop="layers">
<el-input-number
v-model="form.layers"
:min="1"
:max="20"
placeholder="请输入层数"
style="width: 100%" />
</el-form-item>
<el-form-item label="电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入电话" />
</el-form-item>
</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="DormBuildingFormDialog">
import { ref, reactive, nextTick } from 'vue'
import { useMessage } from '/@/hooks/message'
import { addObj, putObj, getObj } from '/@/api/stuwork/dormbuilding'
const emit = defineEmits(['refresh'])
// 定义变量内容
const dataFormRef = ref()
const visible = ref(false)
const loading = ref(false)
const operType = ref('add') // add 或 edit
// 提交表单数据
const form = reactive({
id: '',
buildingNo: '',
layers: undefined as number | undefined,
phone: ''
})
// 定义校验规则
const dataRules = {
buildingNo: [
{ required: true, message: '请输入楼号', trigger: 'blur' }
],
layers: [
{ required: true, message: '请输入层数', trigger: 'blur' },
{ type: 'number', min: 1, max: 20, message: '层数必须在1-20之间', trigger: 'blur' }
],
phone: [
{ required: true, message: '请输入电话', trigger: 'blur' }
]
}
// 打开弹窗
const openDialog = (type: string = 'add', row?: any) => {
visible.value = true
operType.value = type
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields()
form.id = ''
form.buildingNo = ''
form.layers = undefined
form.phone = ''
// 编辑时填充数据
if (type === 'edit' && row) {
form.id = row.id
form.buildingNo = row.buildingNo || ''
form.layers = row.layers
form.phone = row.phone || ''
}
})
}
// 提交表单
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({
buildingNo: form.buildingNo,
layers: form.layers,
phone: form.phone
})
useMessage().success('新增成功')
} else {
await putObj({
id: form.id,
buildingNo: form.buildingNo,
layers: form.layers,
phone: form.phone
})
useMessage().success('编辑成功')
}
visible.value = false
emit('refresh')
} catch (err: any) {
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
} finally {
loading.value = false
}
})
}
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View File

@@ -0,0 +1,251 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 操作按钮 -->
<el-row>
<div class="mb8" style="width: 100%">
<el-button
icon="FolderAdd"
type="primary"
class="ml10"
@click="formDialogRef.openDialog()">
</el-button>
<right-toolbar
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"
@sort-change="sortChangeHandle"
show-summary
:summary-method="getSummaries">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="buildingNo" label="楼号" show-overflow-tooltip align="center" />
<el-table-column prop="layers" label="层数" show-overflow-tooltip align="center" />
<el-table-column prop="allAlreadyNum" label="已住人数" show-overflow-tooltip align="center" />
<el-table-column prop="nowNum" label="现住人数" show-overflow-tooltip align="center" />
<el-table-column prop="surplusNum" label="剩余可住人数" show-overflow-tooltip align="center" />
<el-table-column prop="roomEmptyNum" label="空宿舍数" show-overflow-tooltip align="center">
<template #default="scope">
<el-link
v-if="scope.row.roomEmptyNum > 0"
type="primary"
:underline="false"
@click="handleViewEmptyRoom(scope.row, 'all')">
{{ scope.row.roomEmptyNum }}
</el-link>
<span v-else>{{ scope.row.roomEmptyNum || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="roomEmptyNum5" label="空5人宿舍数" show-overflow-tooltip align="center">
<template #default="scope">
<el-link
v-if="scope.row.roomEmptyNum5 > 0"
type="primary"
:underline="false"
@click="handleViewEmptyRoom(scope.row, '5')">
{{ scope.row.roomEmptyNum5 }}
</el-link>
<span v-else>{{ scope.row.roomEmptyNum5 || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="roomEmptyNum4" label="空4人宿舍数" show-overflow-tooltip align="center">
<template #default="scope">
<el-link
v-if="scope.row.roomEmptyNum4 > 0"
type="primary"
:underline="false"
@click="handleViewEmptyRoom(scope.row, '4')">
{{ scope.row.roomEmptyNum4 }}
</el-link>
<span v-else>{{ scope.row.roomEmptyNum4 || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="roomEmptyNum3" label="空3人宿舍数" show-overflow-tooltip align="center">
<template #default="scope">
<el-link
v-if="scope.row.roomEmptyNum3 > 0"
type="primary"
:underline="false"
@click="handleViewEmptyRoom(scope.row, '3')">
{{ scope.row.roomEmptyNum3 }}
</el-link>
<span v-else>{{ scope.row.roomEmptyNum3 || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="roomEmptyNum2" label="空2人宿舍数" show-overflow-tooltip align="center">
<template #default="scope">
<el-link
v-if="scope.row.roomEmptyNum2 > 0"
type="primary"
:underline="false"
@click="handleViewEmptyRoom(scope.row, '2')">
{{ scope.row.roomEmptyNum2 }}
</el-link>
<span v-else>{{ scope.row.roomEmptyNum2 || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="roomEmptyNum1" label="空1人宿舍数" show-overflow-tooltip align="center">
<template #default="scope">
<el-link
v-if="scope.row.roomEmptyNum1 > 0"
type="primary"
:underline="false"
@click="handleViewEmptyRoom(scope.row, '1')">
{{ scope.row.roomEmptyNum1 }}
</el-link>
<span v-else>{{ scope.row.roomEmptyNum1 || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="phone" 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
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
v-bind="state.pagination" />
</div>
<!-- 编辑新增 -->
<FormDialog ref="formDialogRef" @refresh="getDataList(false)" />
<!-- 空宿舍详情对话框 -->
<EmptyRoomDialog ref="emptyRoomDialogRef" />
</div>
</template>
<script setup lang="ts" name="DormBuilding">
import { ref, reactive, defineAsyncComponent } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, delObjs } from "/@/api/stuwork/dormbuilding";
import { useMessage, useMessageBox } from "/@/hooks/message";
// 引入组件
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
const EmptyRoomDialog = defineAsyncComponent(() => import('./emptyRoomDialog.vue'));
// 定义变量内容
const formDialogRef = ref()
const emptyRoomDialogRef = ref()
// 搜索表单
const searchForm = reactive({
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: fetchList,
props: {
item: 'records',
totalCount: 'total'
}
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
tableStyle
} = useTable(state)
// 编辑
const handleEdit = (row: any) => {
if (formDialogRef.value) {
formDialogRef.value.openDialog('edit', row)
}
}
// 删除
const handleDelete = async (row: any) => {
try {
await useMessageBox().confirm('确定要删除该宿舍楼吗?')
await delObjs([row.id])
useMessage().success('删除成功')
getDataList()
} catch (err: any) {
if (err !== 'cancel') {
useMessage().error(err.msg || '删除失败')
}
}
}
// 合计行统计
const getSummaries = (param: any) => {
const { columns, data } = param
const sums: string[] = []
columns.forEach((column: any, index: number) => {
if (index === 0) {
// 序号列显示"合计"
sums[index] = '合计'
return
}
// 跳过序号、楼号、层数、电话、操作列
const prop = column.property
if (!prop || prop === 'buildingNo' || prop === 'layers' || prop === 'phone') {
sums[index] = ''
return
}
// 统计数值字段
const values = data.map((item: any) => Number(item[prop]))
if (!values.every((value: any) => isNaN(value))) {
const sum = values.reduce((prev: number, curr: number) => {
const value = Number(curr)
if (!isNaN(value)) {
return prev + curr
} else {
return prev
}
}, 0)
sums[index] = sum.toString()
} else {
sums[index] = ''
}
})
return sums
}
// 查看空宿舍详情
const handleViewEmptyRoom = (row: any, roomType: string) => {
if (emptyRoomDialogRef.value) {
emptyRoomDialogRef.value.openDialog(row.buildingNo, roomType)
}
}
</script>

View File

@@ -0,0 +1,77 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 表格 -->
<el-table
:data="state.dataList"
v-loading="state.loading"
border
:cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle"
@sort-change="sortChangeHandle">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="buildingNo" label="楼号" show-overflow-tooltip align="center" />
<el-table-column prop="username" label="管理员工号" show-overflow-tooltip align="center" />
<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="DormBuildingManger">
import { reactive } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, delObjs } from "/@/api/stuwork/dormbuildingmanger";
import { useMessage, useMessageBox } from "/@/hooks/message";
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {},
pageList: fetchList,
props: {
item: 'records',
totalCount: 'total'
},
createdIsNeed: true
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
tableStyle
} = useTable(state)
// 删除
const handleDelete = async (row: any) => {
try {
await useMessageBox().confirm('确定要删除该宿舍管理员吗?')
await delObjs([row.id])
useMessage().success('删除成功')
getDataList()
} catch (err: any) {
if (err !== 'cancel') {
useMessage().error(err.msg || '删除失败')
}
}
}
</script>

View File

@@ -0,0 +1,173 @@
<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-form-item label="楼号" prop="buildingNo">
<el-select
v-model="form.buildingNo"
placeholder="请选择楼号"
clearable
filterable
style="width: 100%">
<el-option
v-for="item in buildingList"
:key="item.buildingNo"
:label="item.buildingNo"
:value="item.buildingNo">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="宿舍号" prop="roomNo">
<el-input v-model="form.roomNo" placeholder="请输入宿舍号" />
</el-form-item>
<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-form-item label="情况记录" prop="note">
<el-input
v-model="form.note"
type="textarea"
:rows="4"
placeholder="请输入情况记录" />
</el-form-item>
</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="DormHygieneDailyFormDialog">
import { ref, reactive, nextTick, onMounted } from 'vue'
import { useMessage } from '/@/hooks/message'
import { addObj, putObj, getObj } from '/@/api/stuwork/dormhygienedaily'
import { getBuildingList } from '/@/api/stuwork/dormbuilding'
const emit = defineEmits(['refresh'])
// 定义变量内容
const dataFormRef = ref()
const visible = ref(false)
const loading = ref(false)
const operType = ref('add') // add 或 edit
const buildingList = ref<any[]>([])
// 提交表单数据
const form = reactive({
id: '',
buildingNo: '',
roomNo: '',
recordDate: '',
note: ''
})
// 定义校验规则
const dataRules = {
buildingNo: [
{ required: true, message: '请选择楼号', trigger: 'change' }
],
roomNo: [
{ required: true, message: '请输入宿舍号', trigger: 'blur' }
],
recordDate: [
{ required: true, message: '请选择记录日期', trigger: 'change' }
],
note: [
{ required: true, message: '请输入情况记录', trigger: 'blur' }
]
}
// 打开弹窗
const openDialog = (type: string = 'add', row?: any) => {
visible.value = true
operType.value = type
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields()
form.id = ''
form.buildingNo = ''
form.roomNo = ''
form.recordDate = ''
form.note = ''
// 编辑时填充数据
if (type === 'edit' && row) {
form.id = row.id
form.buildingNo = row.buildingNo || ''
form.roomNo = row.roomNo || ''
// 处理日期格式
if (row.recordDate) {
form.recordDate = row.recordDate.split(' ')[0] || row.recordDate
}
form.note = row.note || ''
}
})
}
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
loading.value = true
try {
const submitData: any = {
buildingNo: form.buildingNo,
roomNo: form.roomNo,
recordDate: form.recordDate + ' 00:00:00',
note: form.note
}
if (operType.value === 'add') {
await addObj(submitData)
useMessage().success('新增成功')
} else {
submitData.id = form.id
await putObj(submitData)
useMessage().success('编辑成功')
}
visible.value = false
emit('refresh')
} catch (err: any) {
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
} finally {
loading.value = false
}
})
}
// 获取楼号列表
const getBuildingListData = async () => {
try {
const res = await getBuildingList()
if (res.data) {
buildingList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取楼号列表失败', err)
buildingList.value = []
}
}
// 初始化
onMounted(() => {
getBuildingListData()
})
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View File

@@ -0,0 +1,261 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<el-row v-show="showSearch">
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="学年" prop="schoolYear">
<el-select
v-model="searchForm.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="searchForm.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="buildingNo">
<el-select
v-model="searchForm.buildingNo"
placeholder="请选择楼号"
clearable
filterable
style="width: 200px">
<el-option
v-for="item in buildingList"
:key="item.buildingNo"
:label="item.buildingNo"
:value="item.buildingNo">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</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="FolderAdd"
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"
@sort-change="sortChangeHandle">
<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>{{ scope.row.schoolTerm === '1' ? '第一学期' : scope.row.schoolTerm === '2' ? '第二学期' : scope.row.schoolTerm }}</span>
</template>
</el-table-column>
<el-table-column prop="buildingNo" label="楼号" show-overflow-tooltip align="center" />
<el-table-column prop="roomNo" label="宿舍号" show-overflow-tooltip align="center" />
<el-table-column prop="recordDate" label="记录日期" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.recordDate ? scope.row.recordDate.split(' ')[0] : '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="note" 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
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
v-bind="state.pagination" />
</div>
<!-- 编辑新增 -->
<FormDialog ref="formDialogRef" @refresh="getDataList(false)" />
</div>
</template>
<script setup lang="ts" name="DormHygieneDaily">
import { ref, reactive, defineAsyncComponent, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, delObjs } from "/@/api/stuwork/dormhygienedaily";
import { getBuildingList } from "/@/api/stuwork/dormbuilding";
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
import { useMessage, useMessageBox } from "/@/hooks/message";
import { getDicts } from "/@/api/admin/dict";
// 引入组件
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
// 定义变量内容
const formDialogRef = ref()
const searchFormRef = ref()
const showSearch = ref(true)
const schoolYearList = ref<any[]>([])
const schoolTermList = ref<any[]>([])
const buildingList = ref<any[]>([])
// 搜索表单
const searchForm = reactive({
schoolYear: '',
schoolTerm: '',
buildingNo: ''
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: fetchList,
props: {
item: 'records',
totalCount: 'total'
}
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
tableStyle
} = useTable(state)
// 查询
const handleSearch = () => {
getDataList()
}
// 重置
const handleReset = () => {
searchFormRef.value?.formRef?.resetFields()
searchForm.schoolYear = ''
searchForm.schoolTerm = ''
searchForm.buildingNo = ''
getDataList()
}
// 编辑
const handleEdit = (row: any) => {
if (formDialogRef.value) {
formDialogRef.value.openDialog('edit', row)
}
}
// 删除
const handleDelete = async (row: any) => {
try {
await useMessageBox().confirm('确定要删除该记录吗?')
await delObjs([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) {
schoolYearList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取学年列表失败', err)
schoolYearList.value = []
}
}
// 获取学期字典
const getSchoolTermDict = async () => {
try {
const res = await getDicts('school_term')
if (res.data) {
schoolTermList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取学期字典失败', err)
schoolTermList.value = []
}
}
// 获取楼号列表
const getBuildingListData = async () => {
try {
const res = await getBuildingList()
if (res.data) {
buildingList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取楼号列表失败', err)
buildingList.value = []
}
}
// 初始化
onMounted(() => {
getSchoolYearList()
getSchoolTermDict()
getBuildingListData()
})
</script>

View File

@@ -0,0 +1,131 @@
<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-form-item label="房间号" prop="roomNo">
<el-input v-model="form.roomNo" placeholder="请输入房间号" />
</el-form-item>
<el-form-item label="整改时间" prop="reformDate">
<el-date-picker
v-model="form.reformDate"
type="date"
placeholder="选择日期"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
style="width: 100%" />
</el-form-item>
<el-form-item label="整改内容" prop="reformContent">
<el-input
v-model="form.reformContent"
type="textarea"
:rows="4"
placeholder="请输入整改内容" />
</el-form-item>
</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="DormReformFormDialog">
import { ref, reactive, nextTick } from 'vue'
import { useMessage } from '/@/hooks/message'
import { addObj, putObj } from '/@/api/stuwork/dormreform'
const emit = defineEmits(['refresh'])
// 定义变量内容
const dataFormRef = ref()
const visible = ref(false)
const loading = ref(false)
const operType = ref('add') // add 或 edit
// 提交表单数据
const form = reactive({
id: '',
roomNo: '',
reformDate: '',
reformContent: ''
})
// 定义校验规则
const dataRules = {
roomNo: [
{ required: true, message: '请输入房间号', trigger: 'blur' }
],
reformDate: [
{ required: true, message: '请选择整改时间', trigger: 'change' }
],
reformContent: [
{ required: true, message: '请输入整改内容', trigger: 'blur' }
]
}
// 打开弹窗
const openDialog = (type: string = 'add', row?: any) => {
visible.value = true
operType.value = type
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields()
form.id = ''
form.roomNo = ''
form.reformDate = ''
form.reformContent = ''
// 编辑时填充数据
if (type === 'edit' && row) {
form.id = row.id
form.roomNo = row.roomNo || ''
// 处理日期格式
if (row.reformDate) {
form.reformDate = row.reformDate.split(' ')[0] || row.reformDate
}
form.reformContent = row.reformContent || ''
}
})
}
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
loading.value = true
try {
const submitData: any = {
roomNo: form.roomNo,
reformDate: form.reformDate,
reformContent: form.reformContent
}
if (operType.value === 'add') {
await addObj(submitData)
useMessage().success('新增成功')
} else {
submitData.id = form.id
await putObj(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>

View File

@@ -0,0 +1,309 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<el-row v-show="showSearch">
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="楼号" prop="buildingNo">
<el-select
v-model="searchForm.buildingNo"
placeholder="请选择楼号"
clearable
filterable
style="width: 200px">
<el-option
v-for="item in buildingList"
:key="item.buildingNo"
:label="item.buildingNo"
:value="item.buildingNo">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="房间号" prop="roomNo">
<el-input
v-model="searchForm.roomNo"
placeholder="请输入房间号"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="月份" prop="month">
<el-date-picker
v-model="searchForm.month"
type="month"
placeholder="选择月份"
format="YYYY-MM"
value-format="YYYY-MM"
style="width: 200px" />
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</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="FolderAdd"
type="primary"
class="ml10"
@click="formDialogRef.openDialog()">
</el-button>
<el-button
icon="Download"
type="warning"
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"
@sort-change="sortChangeHandle">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
<el-table-column prop="classNos" label="班级" show-overflow-tooltip align="center" />
<el-table-column prop="roomNo" label="房间号" show-overflow-tooltip align="center" />
<el-table-column prop="reformDate" label="整改时间" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.reformDate ? scope.row.reformDate.split(' ')[0] : '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="reformContent" label="整改内容" show-overflow-tooltip align="center" />
<el-table-column prop="reformStatus" label="整改结果" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ formatReformStatus(scope.row.reformStatus) }}</span>
</template>
</el-table-column>
<el-table-column prop="remarks" label="关联扣分明细" show-overflow-tooltip align="center" />
<el-table-column label="操作" width="350" align="center" fixed="right">
<template #default="scope">
<el-button
text
type="success"
@click="handleSetStatus(scope.row, '合格')"
:disabled="isStatusDisabled(scope.row.reformStatus, '合格')">
合格
</el-button>
<el-button
text
type="danger"
@click="handleSetStatus(scope.row, '不合格')"
:disabled="isStatusDisabled(scope.row.reformStatus, '不合格')">
不合格
</el-button>
<el-button
text
type="warning"
@click="handleSetStatus(scope.row, '未整改')"
:disabled="isStatusDisabled(scope.row.reformStatus, '未整改')">
未整改
</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>
<!-- 编辑新增 -->
<FormDialog ref="formDialogRef" @refresh="getDataList(false)" />
</div>
</template>
<script setup lang="ts" name="DormHygieneMonthly">
import { ref, reactive, defineAsyncComponent, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, putObj, delObjs } from "/@/api/stuwork/dormreform";
import { getBuildingList } from "/@/api/stuwork/dormbuilding";
import { useMessage, useMessageBox } from "/@/hooks/message";
import { getDicts } from "/@/api/admin/dict";
import { downBlobFile, adaptationUrl } from "/@/utils/other";
// 引入组件
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
// 定义变量内容
const formDialogRef = ref()
const searchFormRef = ref()
const showSearch = ref(true)
const buildingList = ref<any[]>([])
const reformStatusDict = ref<any[]>([])
// 搜索表单
const searchForm = reactive({
buildingNo: '',
roomNo: '',
month: ''
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: fetchList,
props: {
item: 'records',
totalCount: 'total'
},
createdIsNeed: true
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
tableStyle
} = useTable(state)
// 查询
const handleSearch = () => {
getDataList()
}
// 重置
const handleReset = () => {
searchFormRef.value?.formRef?.resetFields()
searchForm.buildingNo = ''
searchForm.roomNo = ''
searchForm.month = ''
getDataList()
}
// 判断状态按钮是否禁用
const isStatusDisabled = (currentStatus: string | number, targetStatus: string) => {
if (!currentStatus) return false
const currentDictItem = reformStatusDict.value.find(item => item.value == currentStatus)
const currentLabel = currentDictItem ? currentDictItem.label : currentStatus
return currentLabel === targetStatus
}
// 设置整改状态
const handleSetStatus = async (row: any, status: string) => {
try {
// 根据字典值设置整改状态
const statusValue = reformStatusDict.value.find(item => item.label === status)?.value
if (!statusValue) {
useMessage().error('未找到对应的整改状态')
return
}
await putObj({
id: row.id,
roomNo: row.roomNo,
reformDate: row.reformDate ? row.reformDate.split(' ')[0] : row.reformDate,
reformContent: row.reformContent,
reformStatus: statusValue
})
useMessage().success('设置成功')
getDataList()
} catch (err: any) {
useMessage().error(err.msg || '设置失败')
}
}
// 编辑
const handleEdit = (row: any) => {
if (formDialogRef.value) {
formDialogRef.value.openDialog('edit', row)
}
}
// 删除
const handleDelete = async (row: any) => {
try {
await useMessageBox().confirm('确定要删除该记录吗?')
await delObjs([row.id])
useMessage().success('删除成功')
getDataList()
} catch (err: any) {
if (err !== 'cancel') {
useMessage().error(err.msg || '删除失败')
}
}
}
// 导出
const handleExport = () => {
downBlobFile(adaptationUrl('/stuwork/dormreform/export'), searchForm, '月卫生检查整改.xlsx')
}
// 格式化整改结果
const formatReformStatus = (value: string | number) => {
if (value === null || value === undefined || value === '') {
return '-'
}
const dictItem = reformStatusDict.value.find(item => item.value == value)
return dictItem ? dictItem.label : value
}
// 获取楼号列表
const getBuildingListData = async () => {
try {
const res = await getBuildingList()
if (res.data) {
buildingList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取楼号列表失败', err)
buildingList.value = []
}
}
// 获取整改结果字典
const getReformStatusDict = async () => {
try {
const res = await getDicts('reform_status')
if (res.data) {
reformStatusDict.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取整改结果字典失败', err)
reformStatusDict.value = []
}
}
// 初始化
onMounted(() => {
getBuildingListData()
getReformStatusDict()
})
</script>

View File

@@ -0,0 +1,237 @@
<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-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-form-item label="楼号" prop="buildingNo">
<el-select
v-model="form.buildingNo"
placeholder="请选择楼号"
clearable
filterable
style="width: 100%">
<el-option
v-for="item in buildingList"
:key="item.buildingNo"
:label="item.buildingNo"
:value="item.buildingNo">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="房间号" prop="roomNo">
<el-input v-model="form.roomNo" placeholder="请输入房间号" />
</el-form-item>
<el-form-item label="几人间" prop="bedNum">
<el-select
v-model="form.bedNum"
placeholder="请选择几人间"
clearable
style="width: 100%">
<el-option
v-for="item in bedNumList"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="已住人数" prop="livedNum">
<el-input-number
v-model="form.livedNum"
:min="0"
placeholder="请输入已住人数"
style="width: 100%" />
</el-form-item>
<el-form-item label="备注" prop="remarks">
<el-input
v-model="form.remarks"
type="textarea"
:rows="3"
placeholder="请输入备注" />
</el-form-item>
</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="DormRoomFormDialog">
import { ref, reactive, nextTick, onMounted } from 'vue'
import { useMessage } from '/@/hooks/message'
import { addObj, putObj, getObj } from '/@/api/stuwork/dormroom'
import { getDeptList } from '/@/api/basic/basicclass'
import { getBuildingList } from '/@/api/stuwork/dormbuilding'
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') // add 或 edit
const deptList = ref<any[]>([])
const buildingList = ref<any[]>([])
const bedNumList = ref<any[]>([])
// 提交表单数据
const form = reactive({
id: '',
deptCode: '',
buildingNo: '',
roomNo: '',
bedNum: '',
livedNum: 0,
remarks: ''
})
// 定义校验规则
const dataRules = {
buildingNo: [
{ required: true, message: '请选择楼号', trigger: 'change' }
],
roomNo: [
{ required: true, message: '请输入房间号', trigger: 'blur' }
],
bedNum: [
{ required: true, message: '请选择几人间', trigger: 'change' }
]
}
// 打开弹窗
const openDialog = (type: string = 'add', row?: any) => {
visible.value = true
operType.value = type
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields()
form.id = ''
form.deptCode = ''
form.buildingNo = ''
form.roomNo = ''
form.bedNum = ''
form.livedNum = 0
form.remarks = ''
// 编辑时填充数据
if (type === 'edit' && row) {
form.id = row.id
form.deptCode = row.deptCode || ''
form.buildingNo = row.buildingNo || ''
form.roomNo = row.roomNo || ''
form.bedNum = row.bedNum || ''
form.livedNum = row.livedNum || 0
form.remarks = row.remarks || ''
}
})
}
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
loading.value = true
try {
const submitData: any = {
deptCode: form.deptCode || '',
buildingNo: form.buildingNo,
roomNo: form.roomNo,
bedNum: form.bedNum,
livedNum: form.livedNum || '',
remarks: form.remarks || ''
}
if (operType.value === 'add') {
await addObj(submitData)
useMessage().success('新增成功')
} else {
submitData.id = form.id
await putObj(submitData)
useMessage().success('编辑成功')
}
visible.value = false
emit('refresh')
} catch (err: any) {
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
} finally {
loading.value = false
}
})
}
// 获取学院列表
const getDeptListData = async () => {
try {
const res = await getDeptList()
if (res.data) {
deptList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取学院列表失败', err)
deptList.value = []
}
}
// 获取楼号列表
const getBuildingListData = async () => {
try {
const res = await getBuildingList()
if (res.data) {
buildingList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取楼号列表失败', err)
buildingList.value = []
}
}
// 获取几人间字典
const getBedNumDict = async () => {
try {
const res = await getDicts('room_stu_num')
if (res.data) {
bedNumList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取几人间字典失败', err)
bedNumList.value = []
}
}
// 初始化
onMounted(() => {
getDeptListData()
getBuildingListData()
getBedNumDict()
})
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View File

@@ -0,0 +1,379 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<el-row v-show="showSearch">
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="学院" prop="deptCode">
<el-select
v-model="searchForm.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="buildingNo">
<el-select
v-model="searchForm.buildingNo"
placeholder="请选择楼号"
clearable
filterable
style="width: 200px">
<el-option
v-for="item in buildingList"
:key="item.buildingNo"
:label="item.buildingNo"
:value="item.buildingNo">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="房间号" prop="roomNo">
<el-input
v-model="searchForm.roomNo"
placeholder="请输入房间号"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="几人间" prop="bedNum">
<el-select
v-model="searchForm.bedNum"
placeholder="请选择几人间"
clearable
style="width: 200px">
<el-option
v-for="item in bedNumList"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="已住人数" prop="livedNum">
<el-input
v-model="searchForm.livedNum"
placeholder="请输入已住人数"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</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="FolderAdd"
type="primary"
class="ml10"
@click="formDialogRef.openDialog()">
</el-button>
<el-button
icon="OfficeBuilding"
type="success"
class="ml10"
@click="handleDeptAssign">
学院安排
</el-button>
<el-button
icon="Download"
type="warning"
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"
@sort-change="sortChangeHandle"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
<el-table-column prop="buildingNo" label="楼号" show-overflow-tooltip align="center" />
<el-table-column prop="roomNo" label="房间号" show-overflow-tooltip align="center" />
<el-table-column prop="bedNum" label="几人间" show-overflow-tooltip align="center" />
<el-table-column prop="livedNum" label="已住人数" show-overflow-tooltip align="center" />
<el-table-column prop="remarks" 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
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
v-bind="state.pagination" />
</div>
<!-- 编辑新增 -->
<FormDialog ref="formDialogRef" @refresh="getDataList(false)" />
<!-- 学院安排对话框 -->
<el-dialog
v-model="deptAssignDialogVisible"
title="学院安排"
:width="500"
:close-on-click-modal="false">
<el-form :model="deptAssignForm" label-width="100px">
<el-form-item label="学院" required>
<el-select
v-model="deptAssignForm.deptCode"
placeholder="请选择学院"
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-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="deptAssignDialogVisible = false"> </el-button>
<el-button type="primary" @click="confirmDeptAssign" :loading="deptAssignLoading"> </el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts" name="DormRoom">
import { ref, reactive, defineAsyncComponent, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, delObj, editDept } from "/@/api/stuwork/dormroom";
import { getDeptList } from "/@/api/basic/basicclass";
import { getBuildingList } from "/@/api/stuwork/dormbuilding";
import { useMessage, useMessageBox } from "/@/hooks/message";
import { downBlobFile, adaptationUrl } from "/@/utils/other";
import { getDicts } from "/@/api/admin/dict";
// 引入组件
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
// 定义变量内容
const formDialogRef = ref()
const searchFormRef = ref()
const showSearch = ref(true)
const deptList = ref<any[]>([])
const buildingList = ref<any[]>([])
const bedNumList = ref<any[]>([])
const selectedRows = ref<any[]>([])
const deptAssignDialogVisible = ref(false)
const deptAssignLoading = ref(false)
// 搜索表单
const searchForm = reactive({
deptCode: '',
buildingNo: '',
roomNo: '',
bedNum: '',
livedNum: ''
})
// 学院安排表单
const deptAssignForm = reactive({
deptCode: ''
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: fetchList,
props: {
item: 'records',
totalCount: 'total'
}
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
tableStyle
} = useTable(state)
// 多选事件
const handleSelectionChange = (selection: any[]) => {
selectedRows.value = selection
}
// 查询
const handleSearch = () => {
getDataList()
}
// 重置
const handleReset = () => {
searchFormRef.value?.formRef?.resetFields()
searchForm.deptCode = ''
searchForm.buildingNo = ''
searchForm.roomNo = ''
searchForm.bedNum = ''
searchForm.livedNum = ''
getDataList()
}
// 编辑
const handleEdit = (row: any) => {
if (formDialogRef.value) {
formDialogRef.value.openDialog('edit', row)
}
}
// 删除
const handleDelete = async (row: any) => {
try {
await useMessageBox().confirm('确定要删除该宿舍房间吗?')
await delObj(row.id)
useMessage().success('删除成功')
getDataList()
} catch (err: any) {
if (err !== 'cancel') {
useMessage().error(err.msg || '删除失败')
}
}
}
// 学院安排
const handleDeptAssign = () => {
if (selectedRows.value.length === 0) {
useMessage().warning('请先选择要安排的宿舍房间')
return
}
deptAssignDialogVisible.value = true
deptAssignForm.deptCode = ''
}
// 确认学院安排
const confirmDeptAssign = async () => {
if (!deptAssignForm.deptCode) {
useMessage().warning('请选择学院')
return
}
try {
deptAssignLoading.value = true
const ids = selectedRows.value.map((row: any) => row.id)
await editDept({
deptCode: deptAssignForm.deptCode,
ids
})
useMessage().success('安排成功')
deptAssignDialogVisible.value = false
getDataList()
} catch (err: any) {
useMessage().error(err.msg || '安排失败')
} finally {
deptAssignLoading.value = false
}
}
// 导出
const handleExport = async () => {
try {
await downBlobFile(
adaptationUrl('/stuwork/dormroom/export'),
searchForm,
'宿舍房间.xlsx'
)
useMessage().success('导出成功')
} catch (err: any) {
useMessage().error(err.msg || '导出失败')
}
}
// 获取学院列表
const getDeptListData = async () => {
try {
const res = await getDeptList()
if (res.data) {
deptList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取学院列表失败', err)
deptList.value = []
}
}
// 获取楼号列表
const getBuildingListData = async () => {
try {
const res = await getBuildingList()
if (res.data) {
buildingList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取楼号列表失败', err)
buildingList.value = []
}
}
// 获取几人间字典
const getBedNumDict = async () => {
try {
const res = await getDicts('room_stu_num')
if (res.data) {
bedNumList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取几人间字典失败', err)
bedNumList.value = []
}
}
// 初始化
onMounted(() => {
getDeptListData()
getBuildingListData()
getBedNumDict()
})
</script>

View File

@@ -0,0 +1,92 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 表格 -->
<el-table
:data="state.dataList"
v-loading="state.loading"
border
:cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
<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="roomNo" label="房间号" show-overflow-tooltip align="center" />
<el-table-column prop="bedNo" label="床位号" show-overflow-tooltip align="center" />
<el-table-column prop="teacherRealName" label="班主任" show-overflow-tooltip align="center" />
<el-table-column prop="teacherPhone" label="班主任电话" show-overflow-tooltip align="center" />
<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>
</div>
</div>
</template>
<script setup lang="ts" name="DormAbnormal">
import { reactive, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { queryStudentAbnormal } from "/@/api/stuwork/dormroomstudent";
import { useMessage } from "/@/hooks/message";
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {},
isPage: false, // 接口不支持分页
pageList: async () => {
try {
const res = await queryStudentAbnormal()
let dataList = []
if (Array.isArray(res.data)) {
dataList = res.data
} else if (res.data && Array.isArray(res.data.records)) {
dataList = res.data.records
} else if (res.data && Array.isArray(res.data.list)) {
dataList = res.data.list
}
return {
...res,
data: dataList
}
} catch (err: any) {
useMessage().error(err.msg || '获取数据失败')
return {
data: []
}
}
},
props: {
item: 'records',
totalCount: 'total'
},
createdIsNeed: true
})
// table hook
const {
getDataList,
tableStyle
} = useTable(state)
// 查看详情
const handleView = (row: any) => {
// TODO: 实现查看详情功能
console.log('查看详情', row)
}
// 初始化
onMounted(() => {
getDataList()
})
</script>

View File

@@ -0,0 +1,327 @@
<template>
<el-dialog
title="新增住宿生"
v-model="visible"
:close-on-click-modal="false"
draggable
width="800px">
<el-form
ref="dataFormRef"
:model="form"
:rules="dataRules"
label-width="100px"
:validate-on-rule-change="false"
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="realName">
<el-select
v-model="form.stuNo"
placeholder="请选择姓名"
clearable
filterable
style="width: 100%"
:disabled="!form.classCode"
@change="handleStudentChange">
<el-option
v-for="item in studentList"
:key="item.stuNo"
:label="item.realName"
:value="item.stuNo">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="学号" prop="stuNo">
<el-input
v-model="form.stuNo"
placeholder="学号"
disabled />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="房间号" prop="roomNo">
<el-select
v-model="form.roomNo"
placeholder="请选择房间号"
clearable
filterable
style="width: 100%"
@change="handleRoomChange">
<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="12" class="mb20">
<el-form-item label="床位号" prop="bedNo">
<el-select
v-model="form.bedNo"
placeholder="请选择床位号"
clearable
style="width: 100%">
<el-option
v-for="item in bedNoList"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="是否为宿舍长" prop="isLeader">
<el-select
v-model="form.isLeader"
placeholder="请选择"
clearable
style="width: 100%">
<el-option label="是" value="1" />
<el-option label="否" value="0" />
</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="DormRoomStudentFormDialog">
import { ref, reactive, nextTick, onMounted } from 'vue'
import { useMessage } from '/@/hooks/message'
import { addObj } from '/@/api/stuwork/dormroomstudent'
import { getRoomList } from '/@/api/stuwork/dormroom'
import { fearchRoomStuNum } from '/@/api/stuwork/dormroomstudent'
import { getClassListByRole } from '/@/api/basic/basicclass'
import { fetchList as getStudentList } from '/@/api/basic/basicstudentinfo'
const emit = defineEmits(['refresh'])
// 定义变量内容
const dataFormRef = ref()
const visible = ref(false)
const loading = ref(false)
const classList = ref<any[]>([])
const studentList = ref<any[]>([])
const roomList = ref<any[]>([])
const bedNoList = ref<string[]>([])
// 提交表单数据
const form = reactive({
classCode: '',
realName: '',
stuNo: '',
roomNo: '',
bedNo: '',
isLeader: '0'
})
// 定义校验规则
const dataRules = {
classCode: [
{ required: true, message: '请选择班级', trigger: 'change' }
],
stuNo: [
{ required: true, message: '请选择姓名', trigger: 'change' }
],
roomNo: [
{ required: true, message: '请选择房间号', trigger: 'change' }
],
bedNo: [
{ required: true, message: '请选择床位号', trigger: 'change' }
],
isLeader: [
{ required: true, message: '请选择是否为宿舍长', trigger: 'change' }
]
}
// 班级变化时获取学生列表
const handleClassChange = async (classCode: string) => {
if (!classCode) {
studentList.value = []
form.stuNo = ''
form.realName = ''
return
}
try {
const res = await getStudentList({
classCode: classCode,
current: 1,
size: 1000
})
if (res.data && res.data.records) {
studentList.value = res.data.records
} else {
studentList.value = []
}
form.stuNo = ''
form.realName = ''
} catch (err) {
console.error('获取学生列表失败', err)
studentList.value = []
form.stuNo = ''
form.realName = ''
}
}
// 学生选择变化
const handleStudentChange = (stuNo: string) => {
const student = studentList.value.find(item => item.stuNo === stuNo)
if (student) {
form.realName = student.realName || ''
}
}
// 房间号变化时获取床位号列表
const handleRoomChange = async (roomNo: string) => {
if (!roomNo) {
bedNoList.value = []
form.bedNo = ''
return
}
try {
const res = await fearchRoomStuNum(roomNo)
if (res.data) {
// 根据返回的数据结构处理床位号列表
// 假设返回的是数字数组或对象数组
if (Array.isArray(res.data)) {
bedNoList.value = res.data.map((item: any) => {
if (typeof item === 'number' || typeof item === 'string') {
return String(item)
}
return String(item.bedNo || item.value || item)
})
} else if (res.data.bedNos && Array.isArray(res.data.bedNos)) {
bedNoList.value = res.data.bedNos.map((item: any) => String(item))
} else {
bedNoList.value = []
}
} else {
bedNoList.value = []
}
form.bedNo = ''
} catch (err) {
console.error('获取床位号列表失败', err)
bedNoList.value = []
form.bedNo = ''
}
}
// 打开弹窗
const openDialog = async () => {
visible.value = true
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields()
form.classCode = ''
form.realName = ''
form.stuNo = ''
form.roomNo = ''
form.bedNo = ''
form.isLeader = '0'
studentList.value = []
bedNoList.value = []
})
}
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
loading.value = true
try {
await addObj({
roomNo: form.roomNo,
bedNo: form.bedNo,
stuNo: form.stuNo,
isLeader: form.isLeader
})
useMessage().success('新增成功')
visible.value = false
emit('refresh')
} catch (err: any) {
useMessage().error(err.msg || '新增失败')
} finally {
loading.value = false
}
})
}
// 获取班级列表
const getClassListData = async () => {
try {
const res = await getClassListByRole()
if (res.data) {
classList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取班级列表失败', err)
classList.value = []
}
}
// 获取房间号列表
const getRoomListData = async () => {
try {
const res = await getRoomList()
if (res.data) {
roomList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取房间号列表失败', err)
roomList.value = []
}
}
// 初始化
onMounted(() => {
getClassListData()
getRoomListData()
})
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View File

@@ -0,0 +1,410 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<el-row v-show="showSearch">
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="学院" prop="deptCode">
<el-select
v-model="searchForm.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="buildingNo">
<el-select
v-model="searchForm.buildingNo"
placeholder="请选择楼号"
clearable
filterable
style="width: 200px">
<el-option
v-for="item in buildingList"
:key="item.buildingNo"
:label="item.buildingNo"
:value="item.buildingNo">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-select
v-model="searchForm.gender"
placeholder="请选择性别"
clearable
style="width: 200px">
<el-option label="男" value="1" />
<el-option label="女" value="2" />
</el-select>
</el-form-item>
<el-form-item label="筛选类型" prop="dormdataType">
<el-select
v-model="searchForm.dormdataType"
placeholder="请选择筛选类型"
clearable
style="width: 200px"
@change="handleDormDataTypeChange">
<el-option label="所有" value="" />
<el-option label="空宿舍" value="0" />
<el-option label="空1人宿舍" value="1" />
<el-option label="空2人宿舍" value="2" />
<el-option label="空3人宿舍" value="3" />
<el-option label="空4人宿舍" value="4" />
<el-option label="空5人宿舍" value="5" />
</el-select>
</el-form-item>
<el-form-item label="宿舍号" prop="roomNo">
<TreeSelect
v-model="searchForm.roomNo"
:options="dormRoomTreeList"
:objMap="treeProps"
placeholder="请选择宿舍号"
style="width: 200px" />
</el-form-item>
<el-form-item label="房间号" prop="roomNoInput">
<el-input
v-model="searchForm.roomNoInput"
placeholder="请输入房间号"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="班号" prop="classNo">
<el-input
v-model="searchForm.classNo"
placeholder="请输入班号"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="学号" prop="stuNo">
<el-input
v-model="searchForm.stuNo"
placeholder="请输入学号"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="姓名" prop="realName">
<el-input
v-model="searchForm.realName"
placeholder="请输入姓名"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</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="FolderAdd"
type="primary"
class="ml10"
@click="formDialogRef.openDialog()">
新增住宿生
</el-button>
<el-button
icon="Printer"
type="success"
class="ml10"
@click="handlePrintCard">
打印宿舍卡
</el-button>
<el-button
icon="Switch"
type="warning"
class="ml10"
@click="handleRoomSwap">
宿舍互换
</el-button>
<el-button
icon="Download"
type="info"
class="ml10"
@click="handleExport">
</el-button>
<el-button
icon="Document"
type="primary"
plain
class="ml10"
@click="handleExportList">
名单导出
</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"
@sort-change="sortChangeHandle">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="deptName" label="学院" show-overflow-tooltip align="center" />
<el-table-column prop="roomNo" 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="teacherPhone" 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="bedNo" label="床位号" show-overflow-tooltip align="center" />
<el-table-column prop="isLeader" label="是否舍长" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.isLeader === '1' || scope.row.isLeader === 1 ? '是' : '否' }}</span>
</template>
</el-table-column>
<el-table-column prop="phone" label="学生电话" show-overflow-tooltip align="center" />
<el-table-column prop="tel" label="家长电话" show-overflow-tooltip align="center" />
<el-table-column label="操作" width="150" align="center" fixed="right">
<template #default="scope">
<el-button
icon="Switch"
text
type="primary"
@click="handleTransfer(scope.row)">
转宿
</el-button>
<el-button
icon="Delete"
text
type="danger"
@click="handleCheckout(scope.row)">
退宿
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
v-bind="state.pagination" />
</div>
<!-- 新增/转宿表单弹窗 -->
<FormDialog ref="formDialogRef" @refresh="getDataList" />
<!-- 转宿弹窗 -->
<TransferDialog ref="transferDialogRef" @refresh="getDataList" />
</div>
</template>
<script setup lang="ts" name="DormRoomStudent">
import { reactive, ref, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, delObjs } from "/@/api/stuwork/dormroomstudent";
import { getDeptList } from "/@/api/basic/basicclass";
import { getBuildingList } from "/@/api/stuwork/dormbuilding";
import { fetchDormRoomTreeList } from "/@/api/stuwork/dormroom";
import { useMessage, useMessageBox } from "/@/hooks/message";
import FormDialog from './form.vue';
import TransferDialog from './transfer.vue';
import TreeSelect from '/@/components/TreeSelect/index.vue';
// 定义变量内容
const formDialogRef = ref()
const transferDialogRef = ref()
const searchFormRef = ref()
const showSearch = ref(true)
const deptList = ref<any[]>([])
const buildingList = ref<any[]>([])
const dormRoomTreeList = ref<any[]>([])
// 树形选择器配置
const treeProps = {
value: 'id', // 值字段
label: 'id', // 显示字段id 和 name 一样,所以直接用 id
children: 'children' // 子节点字段
}
// 搜索表单
const searchForm = reactive({
deptCode: '',
buildingNo: '',
gender: '',
dormdataType: '', // 筛选类型:空宿舍、空几人宿舍等
roomNo: '', // 树形选择的宿舍号
roomNoInput: '', // 手动输入的房间号
classNo: '',
stuNo: '',
realName: ''
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: async (queryParams: any) => {
// 处理查询参数:如果树形选择有值,优先使用树形选择的值;否则使用手动输入的值
const params = {
...queryParams,
roomNo: queryParams.roomNo || queryParams.roomNoInput || ''
}
// 移除 roomNoInput只保留 roomNo
delete params.roomNoInput
return await fetchList(params)
},
props: {
item: 'records',
totalCount: 'total'
},
createdIsNeed: true
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
tableStyle
} = useTable(state)
// 查询
const handleSearch = () => {
getDataList()
}
// 重置
const handleReset = () => {
searchFormRef.value?.resetFields()
searchForm.deptCode = ''
searchForm.buildingNo = ''
searchForm.gender = ''
searchForm.dormdataType = ''
searchForm.roomNo = ''
searchForm.roomNoInput = ''
searchForm.classNo = ''
searchForm.stuNo = ''
searchForm.realName = ''
// 重置时重新获取所有宿舍树形列表
getDormRoomTreeListData()
getDataList()
}
// 筛选类型变化时重新获取树形列表
const handleDormDataTypeChange = (dormdataType: string) => {
// 清空已选择的宿舍号
searchForm.roomNo = ''
// 重新获取树形列表
getDormRoomTreeListData(dormdataType)
}
// 打印宿舍卡
const handlePrintCard = () => {
useMessage().warning('功能开发中')
}
// 宿舍互换
const handleRoomSwap = () => {
useMessage().warning('功能开发中')
}
// 导出
const handleExport = () => {
useMessage().warning('功能开发中')
}
// 名单导出
const handleExportList = () => {
useMessage().warning('功能开发中')
}
// 转宿
const handleTransfer = (row: any) => {
transferDialogRef.value.openDialog(row)
}
// 退宿
const handleCheckout = async (row: any) => {
try {
await useMessageBox().confirm('确定要退宿该学生吗?')
await delObjs([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) {
deptList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取学院列表失败', err)
deptList.value = []
}
}
// 获取楼号列表
const getBuildingListData = async () => {
try {
const res = await getBuildingList()
if (res.data) {
buildingList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取楼号列表失败', err)
buildingList.value = []
}
}
// 获取宿舍树状列表
const getDormRoomTreeListData = async (dormdataType?: string) => {
try {
const res = await fetchDormRoomTreeList(dormdataType || searchForm.dormdataType)
if (res.data) {
// 处理树状数据,确保数据结构符合 TreeSelect 组件要求
dormRoomTreeList.value = Array.isArray(res.data) ? res.data : []
// 如果返回的数据结构不同,可能需要转换
// 例如:如果返回的是 { buildingNo: '1', rooms: [...] } 的结构
// 需要转换为树形结构
if (dormRoomTreeList.value.length === 0 && res.data) {
// 尝试处理不同的数据结构
if (typeof res.data === 'object' && !Array.isArray(res.data)) {
// 如果是对象,可能需要转换为数组
dormRoomTreeList.value = [res.data]
}
}
}
} catch (err) {
console.error('获取宿舍树状列表失败', err)
dormRoomTreeList.value = []
}
}
// 初始化
onMounted(() => {
getDeptListData()
getBuildingListData()
getDormRoomTreeListData()
})
</script>

View File

@@ -0,0 +1,227 @@
<template>
<el-dialog
title="转宿"
v-model="visible"
:close-on-click-modal="false"
draggable
width="800px">
<el-form
ref="dataFormRef"
:model="form"
:rules="dataRules"
label-width="100px"
:validate-on-rule-change="false"
v-loading="loading">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="房间号" prop="roomNo">
<el-select
v-model="form.roomNo"
placeholder="请选择房间号"
clearable
filterable
style="width: 100%"
@change="handleRoomChange">
<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="12" class="mb20">
<el-form-item label="床位号" prop="bedNo">
<el-select
v-model="form.bedNo"
placeholder="请选择床位号"
clearable
style="width: 100%">
<el-option
v-for="item in bedNoList"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="学号" prop="stuNo">
<el-input
v-model="form.stuNo"
placeholder="请输入学号"
disabled />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="是否舍长" prop="isLeader">
<el-select
v-model="form.isLeader"
placeholder="请选择"
clearable
style="width: 100%">
<el-option label="是" value="1" />
<el-option label="否" value="0" />
</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="DormRoomStudentTransferDialog">
import { ref, reactive, nextTick, onMounted } from 'vue'
import { useMessage } from '/@/hooks/message'
import { editObj } from '/@/api/stuwork/dormroomstudent'
import { getRoomList } from '/@/api/stuwork/dormroom'
import { fearchRoomStuNum } from '/@/api/stuwork/dormroomstudent'
const emit = defineEmits(['refresh'])
// 定义变量内容
const dataFormRef = ref()
const visible = ref(false)
const loading = ref(false)
const roomList = ref<any[]>([])
const bedNoList = ref<string[]>([])
// 提交表单数据
const form = reactive({
id: '',
roomNo: '',
bedNo: '',
stuNo: '',
isLeader: '0'
})
// 定义校验规则
const dataRules = {
roomNo: [
{ required: true, message: '请选择房间号', trigger: 'change' }
],
bedNo: [
{ required: true, message: '请选择床位号', trigger: 'change' }
],
isLeader: [
{ required: true, message: '请选择是否舍长', trigger: 'change' }
]
}
// 房间号变化时获取床位号列表
const handleRoomChange = async (roomNo: string) => {
if (!roomNo) {
bedNoList.value = []
form.bedNo = ''
return
}
try {
const res = await fearchRoomStuNum(roomNo)
if (res.data) {
if (Array.isArray(res.data)) {
bedNoList.value = res.data.map((item: any) => {
if (typeof item === 'number' || typeof item === 'string') {
return String(item)
}
return String(item.bedNo || item.value || item)
})
} else if (res.data.bedNos && Array.isArray(res.data.bedNos)) {
bedNoList.value = res.data.bedNos.map((item: any) => String(item))
} else {
bedNoList.value = []
}
} else {
bedNoList.value = []
}
form.bedNo = ''
} catch (err) {
console.error('获取床位号列表失败', err)
bedNoList.value = []
form.bedNo = ''
}
}
// 打开弹窗
const openDialog = async (row: any) => {
visible.value = true
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields()
form.id = row.id || ''
form.roomNo = row.roomNo || ''
form.bedNo = row.bedNo || ''
form.stuNo = row.stuNo || ''
form.isLeader = row.isLeader || '0'
bedNoList.value = []
// 如果有房间号,获取床位号列表
if (form.roomNo) {
handleRoomChange(form.roomNo)
}
})
}
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
loading.value = true
try {
await editObj({
id: form.id,
roomNo: form.roomNo,
bedNo: form.bedNo,
stuNo: form.stuNo,
isLeader: form.isLeader
})
useMessage().success('转宿成功')
visible.value = false
emit('refresh')
} catch (err: any) {
useMessage().error(err.msg || '转宿失败')
} finally {
loading.value = false
}
})
}
// 获取房间号列表
const getRoomListData = async () => {
try {
const res = await getRoomList()
if (res.data) {
roomList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取房间号列表失败', err)
roomList.value = []
}
}
// 初始化
onMounted(() => {
getRoomListData()
})
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View File

@@ -0,0 +1,245 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<el-row v-show="showSearch">
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="学院" prop="deptCode">
<el-select
v-model="searchForm.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-input
v-model="searchForm.classNo"
placeholder="请输入班号"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="异动类型" prop="changeType">
<el-select
v-model="searchForm.changeType"
placeholder="请选择异动类型"
clearable
style="width: 200px">
<el-option
v-for="item in changeTypeList"
: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="handleSearch">查询</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="createTime" label="变动时间" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.createTime ? scope.row.createTime.split(' ')[0] + ' ' + scope.row.createTime.split(' ')[1] : '-' }}</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="stuNo" label="学号" show-overflow-tooltip align="center" />
<el-table-column prop="realName" label="姓名" show-overflow-tooltip align="center" />
<el-table-column prop="changeType" label="异动类型" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ formatChangeType(scope.row.changeType) }}</span>
</template>
</el-table-column>
<el-table-column prop="roomNo" label="原房间号" show-overflow-tooltip align="center" />
<el-table-column prop="bedNo" label="原床位号" show-overflow-tooltip align="center" />
<el-table-column prop="newRoomNo" label="新房间号" show-overflow-tooltip align="center" />
<el-table-column prop="newBedNo" label="新床位号" show-overflow-tooltip align="center" />
<el-table-column label="操作" width="100" 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>
</div>
</div>
</template>
<script setup lang="ts" name="DormRoomStudentChange">
import { reactive, ref, onMounted, computed } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { queryStudentAbnormal } from "/@/api/stuwork/dormroomstudent";
import { getDeptList } from "/@/api/basic/basicclass";
import { useMessage } from "/@/hooks/message";
import { getDicts } from "/@/api/admin/dict";
// 定义变量内容
const searchFormRef = ref()
const showSearch = ref(true)
const deptList = ref<any[]>([])
const changeTypeList = ref<any[]>([])
const allDataList = ref<any[]>([])
// 搜索表单
const searchForm = reactive({
deptCode: '',
classNo: '',
changeType: ''
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
isPage: false, // 接口不支持分页
pageList: async () => {
try {
const res = await queryStudentAbnormal()
let dataList = []
if (Array.isArray(res.data)) {
dataList = res.data
} else if (res.data && Array.isArray(res.data.records)) {
dataList = res.data.records
} else if (res.data && Array.isArray(res.data.list)) {
dataList = res.data.list
}
allDataList.value = dataList
return {
...res,
data: filterData(dataList)
}
} catch (err: any) {
useMessage().error(err.msg || '获取数据失败')
return {
data: []
}
}
},
props: {
item: 'records',
totalCount: 'total'
},
createdIsNeed: true
})
// 过滤数据
const filterData = (data: any[]) => {
let filtered = data
if (searchForm.deptCode) {
filtered = filtered.filter(item => item.deptCode === searchForm.deptCode)
}
if (searchForm.classNo) {
filtered = filtered.filter(item => item.classNo && item.classNo.includes(searchForm.classNo))
}
if (searchForm.changeType) {
filtered = filtered.filter(item => item.changeType === searchForm.changeType)
}
return filtered
}
// table hook
const {
getDataList,
tableStyle
} = useTable(state)
// 查询
const handleSearch = () => {
getDataList()
}
// 重置
const handleReset = () => {
searchFormRef.value?.formRef?.resetFields()
searchForm.deptCode = ''
searchForm.classNo = ''
searchForm.changeType = ''
getDataList()
}
// 查看详情
const handleView = (row: any) => {
// TODO: 实现查看详情功能
console.log('查看详情', row)
}
// 格式化异动类型
const formatChangeType = (value: string | number) => {
if (value === null || value === undefined || value === '') {
return '-'
}
const dictItem = changeTypeList.value.find(item => item.value == value)
return dictItem ? dictItem.label : value
}
// 获取学院列表
const getDeptListData = async () => {
try {
const res = await getDeptList()
if (res.data) {
deptList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取学院列表失败', err)
deptList.value = []
}
}
// 获取异动类型字典
const getChangeTypeDict = async () => {
try {
const res = await getDicts('change_type')
if (res.data) {
changeTypeList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取异动类型字典失败', err)
changeTypeList.value = []
}
}
// 初始化
onMounted(() => {
getDeptListData()
getChangeTypeDict()
})
</script>

View File

@@ -0,0 +1,195 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<el-row v-show="showSearch">
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="学院" prop="deptCode">
<el-select
v-model="searchForm.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="searchForm.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="handleSearch">查询</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="deptName" label="学院" show-overflow-tooltip align="center" />
<el-table-column prop="classNo" label="班级" show-overflow-tooltip align="center" />
<el-table-column prop="pendingWork" label="待办事项" show-overflow-tooltip align="center" />
<el-table-column prop="nums" label="数量" show-overflow-tooltip align="center">
<template #default="scope">
<el-tag type="warning" v-if="scope.row.nums > 0">{{ scope.row.nums }}</el-tag>
<span v-else>{{ scope.row.nums || 0 }}</span>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip align="center" width="180">
<template #default="scope">
<span>{{ scope.row.createTime ? scope.row.createTime.split(' ')[0] + ' ' + scope.row.createTime.split(' ')[1] : '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="updateTime" label="更新时间" show-overflow-tooltip align="center" width="180">
<template #default="scope">
<span>{{ scope.row.updateTime ? scope.row.updateTime.split(' ')[0] + ' ' + scope.row.updateTime.split(' ')[1] : '-' }}</span>
</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>
<!-- 分页 -->
<pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
v-bind="state.pagination" />
</div>
</div>
</template>
<script setup lang="ts" name="PendingWork">
import { reactive, ref, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList } from "/@/api/stuwork/pendingwork";
import { getDeptList } from "/@/api/basic/basicclass";
import { getClassListByRole } from "/@/api/basic/basicclass";
import { useMessage } from "/@/hooks/message";
// 定义变量内容
const searchFormRef = ref()
const showSearch = ref(true)
const deptList = ref<any[]>([])
const classList = ref<any[]>([])
// 搜索表单
const searchForm = reactive({
deptCode: '',
classCode: ''
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: fetchList,
props: {
item: 'records',
totalCount: 'total'
},
createdIsNeed: true
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
tableStyle
} = useTable(state)
// 查询
const handleSearch = () => {
getDataList()
}
// 重置
const handleReset = () => {
searchFormRef.value?.resetFields()
searchForm.deptCode = ''
searchForm.classCode = ''
getDataList()
}
// 查看详情
const handleView = (row: any) => {
useMessage().warning('查看详情功能待实现')
console.log('查看详情', row)
}
// 获取学院列表
const getDeptListData = async () => {
try {
const res = await getDeptList()
if (res.data) {
deptList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取学院列表失败', err)
deptList.value = []
}
}
// 获取班级列表
const getClassListData = async () => {
try {
const res = await getClassListByRole()
if (res.data) {
classList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取班级列表失败', err)
classList.value = []
}
}
// 初始化
onMounted(() => {
getDeptListData()
getClassListData()
})
</script>

View File

@@ -0,0 +1,149 @@
<template>
<el-dialog
title="新增工学交替"
v-model="visible"
:close-on-click-modal="false"
draggable
width="800px">
<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="dateRange">
<el-date-picker
v-model="form.dateRange"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-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="StuWorkStudyAlternateFormDialog">
import { ref, reactive, nextTick, onMounted } from 'vue'
import { useMessage } from '/@/hooks/message'
import { addObj } from '/@/api/stuwork/stuworkstudyalternate'
import { getClassListByRole } from '/@/api/basic/basicclass'
const emit = defineEmits(['refresh'])
// 定义变量内容
const dataFormRef = ref()
const visible = ref(false)
const loading = ref(false)
const classList = ref<any[]>([])
// 提交表单数据
const form = reactive({
classCode: '',
dateRange: null as [string, string] | null
})
// 定义校验规则
const dataRules = {
classCode: [
{ required: true, message: '请选择班级', trigger: 'change' }
],
dateRange: [
{ required: true, message: '请选择工学交替日期范围', trigger: 'change' }
]
}
// 打开弹窗
const openDialog = async () => {
visible.value = true
nextTick(() => {
dataFormRef.value?.resetFields()
form.classCode = ''
form.dateRange = null
})
}
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
if (!form.dateRange || form.dateRange.length !== 2) {
useMessage().error('请选择日期范围')
return
}
loading.value = true
try {
await addObj({
classCode: form.classCode,
dateRange: form.dateRange
})
useMessage().success('新增成功')
visible.value = false
emit('refresh')
} catch (err: any) {
useMessage().error(err.msg || '新增失败')
} finally {
loading.value = false
}
})
}
// 获取班级列表
const getClassListData = async () => {
try {
const res = await getClassListByRole()
if (res.data) {
classList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取班级列表失败', err)
classList.value = []
}
}
// 初始化
onMounted(() => {
getClassListData()
})
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View 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="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="学年" prop="schoolYear">
<el-select
v-model="searchForm.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="searchForm.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="searchForm.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-input
v-model="searchForm.classNo"
placeholder="请输入班号"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="学号" prop="stuNo">
<el-input
v-model="searchForm.stuNo"
placeholder="请输入学号"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="姓名" prop="realName">
<el-input
v-model="searchForm.realName"
placeholder="请输入姓名"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="日期范围" prop="dateRange">
<el-date-picker
v-model="searchForm.dateRange"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
clearable
style="width: 240px" />
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</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="FolderAdd"
type="primary"
class="ml10"
@click="formDialogRef.openDialog()">
</el-button>
<el-button
icon="User"
type="success"
class="ml10"
@click="teacherDialogRef.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" />
<el-table-column prop="deptName" 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="classNo" label="班号" show-overflow-tooltip align="center" />
<el-table-column prop="className" label="班级简称" show-overflow-tooltip align="center" />
<el-table-column prop="startTime" label="工学交替开始时间" show-overflow-tooltip align="center" width="180">
<template #default="scope">
<span>{{ scope.row.startTime ? scope.row.startTime.split(' ')[0] : '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="endTime" label="工学交替结束时间" show-overflow-tooltip align="center" width="180">
<template #default="scope">
<span>{{ scope.row.endTime ? scope.row.endTime.split(' ')[0] : '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="attendanceTeacherName" label="带班教师" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.attendanceTeacherName || '-' }}</span>
</template>
</el-table-column>
<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>
<!-- 新增表单弹窗 -->
<form-dialog ref="formDialogRef" @refresh="getDataList" />
<!-- 指定带班教师弹窗 -->
<teacher-dialog ref="teacherDialogRef" @refresh="getDataList" />
</div>
</template>
<script setup lang="ts" name="StuWorkStudyAlternate">
import { reactive, ref, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, delObj } from "/@/api/stuwork/stuworkstudyalternate";
import { getDeptList } 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 TeacherDialog from './teacher.vue'
// 定义变量内容
const searchFormRef = ref()
const showSearch = ref(true)
const deptList = ref<any[]>([])
const schoolYearList = ref<any[]>([])
const schoolTermList = ref<any[]>([])
const formDialogRef = ref()
const teacherDialogRef = ref()
// 搜索表单
const searchForm = reactive({
schoolYear: '',
schoolTerm: '',
deptCode: '',
classNo: '',
stuNo: '',
realName: '',
dateRange: null as [string, string] | null
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: fetchList,
props: {
item: 'tableData.records',
totalCount: 'tableData.total'
},
createdIsNeed: true
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
tableStyle
} = useTable(state)
// 查询
const handleSearch = () => {
// 处理日期范围
const params: any = { ...searchForm }
if (searchForm.dateRange && searchForm.dateRange.length === 2) {
params.dateRangeStr = `${searchForm.dateRange[0]},${searchForm.dateRange[1]}`
}
delete params.dateRange
// 处理学年数组
if (params.schoolYear) {
params.schoolYear = [params.schoolYear]
}
// 更新查询参数
Object.assign(searchForm, params)
getDataList()
}
// 重置
const handleReset = () => {
searchFormRef.value?.resetFields()
searchForm.schoolYear = ''
searchForm.schoolTerm = ''
searchForm.deptCode = ''
searchForm.classNo = ''
searchForm.stuNo = ''
searchForm.realName = ''
searchForm.dateRange = null
getDataList()
}
// 删除
const handleDelete = async (row: any) => {
try {
await useMessageBox().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) {
deptList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取学院列表失败', err)
deptList.value = []
}
}
// 获取学年列表
const getSchoolYearList = async () => {
try {
const res = await queryAllSchoolYear()
if (res.data && Array.isArray(res.data)) {
schoolYearList.value = res.data
}
} catch (err) {
console.error('获取学年列表失败', err)
schoolYearList.value = []
}
}
// 获取学期列表
const getSchoolTermList = async () => {
try {
const res = await getDicts('school_term')
if (res.data && Array.isArray(res.data)) {
schoolTermList.value = res.data
}
} catch (err) {
console.error('获取学期列表失败', err)
schoolTermList.value = []
}
}
// 初始化
onMounted(() => {
getDeptListData()
getSchoolYearList()
getSchoolTermList()
})
</script>

View File

@@ -0,0 +1,211 @@
<template>
<el-dialog
title="指定带班教师"
v-model="visible"
:close-on-click-modal="false"
draggable
width="600px">
<el-form
ref="dataFormRef"
:model="form"
:rules="dataRules"
label-width="120px"
v-loading="loading">
<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-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-form-item label="班号" prop="classNo">
<el-input
v-model="form.classNo"
placeholder="请输入班号"
clearable
style="width: 100%" />
</el-form-item>
<el-form-item label="教师" prop="teacherNo">
<el-select
v-model="form.teacherNo"
placeholder="请选择教师"
clearable
filterable
style="width: 100%"
@search="handleTeacherSearch">
<el-option
v-for="item in teacherList"
:key="item.teacherNo"
:label="`${item.realName}(${item.teacherNo})`"
:value="item.teacherNo">
</el-option>
</el-select>
</el-form-item>
</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="StuWorkStudyAlternateTeacherDialog">
import { ref, reactive, nextTick, onMounted } from 'vue'
import { useMessage } from '/@/hooks/message'
import { chooseTeacherAttendance } from '/@/api/stuwork/stuworkstudyalternate'
import { queryAllSchoolYear } from '/@/api/basic/basicyear'
import { getDicts } from '/@/api/admin/dict'
import { getTeacherInfoCommon } from '/@/api/professional/professionaluser/teacherbase'
const emit = defineEmits(['refresh'])
// 定义变量内容
const dataFormRef = ref()
const visible = ref(false)
const loading = ref(false)
const schoolYearList = ref<any[]>([])
const schoolTermList = ref<any[]>([])
const teacherList = ref<any[]>([])
// 提交表单数据
const form = reactive({
schoolYear: '',
schoolTerm: '',
classNo: '',
teacherNo: ''
})
// 定义校验规则
const dataRules = {
schoolYear: [
{ required: true, message: '请选择学年', trigger: 'change' }
],
schoolTerm: [
{ required: true, message: '请选择学期', trigger: 'change' }
],
classNo: [
{ required: true, message: '请输入班号', trigger: 'blur' }
],
teacherNo: [
{ required: true, message: '请选择教师', trigger: 'change' }
]
}
// 教师搜索
const handleTeacherSearch = async (keyword: string) => {
if (!keyword) {
teacherList.value = []
return
}
try {
const res = await getTeacherInfoCommon({ searchKeywords: keyword })
if (res.data && Array.isArray(res.data)) {
teacherList.value = res.data
}
} catch (err) {
console.error('搜索教师失败', err)
teacherList.value = []
}
}
// 打开弹窗
const openDialog = async () => {
visible.value = true
nextTick(() => {
dataFormRef.value?.resetFields()
form.schoolYear = ''
form.schoolTerm = ''
form.classNo = ''
form.teacherNo = ''
teacherList.value = []
})
}
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
loading.value = true
try {
await chooseTeacherAttendance({
schoolYear: form.schoolYear,
schoolTerm: form.schoolTerm,
classNo: form.classNo,
teacherNo: form.teacherNo
})
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)
schoolYearList.value = []
}
}
// 获取学期列表
const getSchoolTermList = async () => {
try {
const res = await getDicts('school_term')
if (res.data && Array.isArray(res.data)) {
schoolTermList.value = res.data
}
} catch (err) {
console.error('获取学期列表失败', err)
schoolTermList.value = []
}
}
// 初始化
onMounted(() => {
getSchoolYearList()
getSchoolTermList()
})
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View File

@@ -0,0 +1,114 @@
<template>
<el-dialog
title="水电明细"
v-model="visible"
:close-on-click-modal="false"
draggable
width="1200px">
<el-table
:data="detailList"
v-loading="loading"
border
:cell-style="{ textAlign: 'center' }"
:header-cell-style="{ textAlign: 'center', background: 'var(--el-table-row-hover-bg-color)' }">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="year" label="年份" show-overflow-tooltip align="center" />
<el-table-column prop="month" label="月份" show-overflow-tooltip align="center" />
<el-table-column prop="subiMonthSum" label="用量" show-overflow-tooltip align="center" />
<el-table-column prop="subWatFlagSum" label="费用" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.subWatFlagSum ? Number(scope.row.subWatFlagSum).toFixed(2) : '0.00' }}</span>
</template>
</el-table-column>
<el-table-column prop="flag" label="用电用水" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ formatFlag(scope.row.flag) }}</span>
</template>
</el-table-column>
<el-table-column prop="meterNum" label="冷水热水" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ formatMeterNum(scope.row.meterNum) }}</span>
</template>
</el-table-column>
</el-table>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts" name="WaterDetailDialog">
import { ref, onMounted } from 'vue'
import { useMessage } from '/@/hooks/message'
import { lookDetails } from '/@/api/stuwork/watermonthreport'
// 定义变量内容
const visible = ref(false)
const loading = ref(false)
const detailList = ref<any[]>([])
const currentRoomNo = ref('')
// 格式化用电用水
const formatFlag = (value: string | number) => {
if (value === '1' || value === 1) {
return '用电'
} else if (value === '2' || value === 2) {
return '用水'
}
return value || '-'
}
// 格式化冷水热水
const formatMeterNum = (value: string | number) => {
if (value === '11' || value === 11) {
return '冷水'
} else if (value === '12' || value === 12) {
return '热水'
}
return value || '-'
}
// 打开弹窗
const openDialog = async (roomNo: string) => {
visible.value = true
currentRoomNo.value = roomNo
detailList.value = []
// 获取明细数据
await getDetailData(roomNo)
}
// 获取明细数据
const getDetailData = async (roomNo: string) => {
loading.value = true
try {
const res = await lookDetails(roomNo)
if (res.data) {
if (Array.isArray(res.data)) {
detailList.value = res.data
} else if (res.data.records && Array.isArray(res.data.records)) {
detailList.value = res.data.records
} else if (res.data.list && Array.isArray(res.data.list)) {
detailList.value = res.data.list
} else {
detailList.value = []
}
} else {
detailList.value = []
}
} catch (err: any) {
useMessage().error(err.msg || '获取明细数据失败')
detailList.value = []
} finally {
loading.value = false
}
}
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View File

@@ -0,0 +1,279 @@
<template>
<el-dialog
:title="form.id ? '编辑' : '新增'"
v-model="visible"
:close-on-click-modal="false"
draggable
width="800px">
<el-form
ref="dataFormRef"
:model="form"
:rules="dataRules"
label-width="100px"
:validate-on-rule-change="false"
v-loading="loading">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="楼号" prop="buildNo">
<el-select
v-model="form.buildNo"
placeholder="请选择楼号"
clearable
filterable
style="width: 100%">
<el-option
v-for="item in buildingList"
:key="item.buildingNo"
:label="item.buildingNo"
:value="item.buildingNo">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="宿舍号" prop="roomNo">
<el-input v-model="form.roomNo" placeholder="请输入宿舍号" />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="几人间" prop="bedNum">
<el-select
v-model="form.bedNum"
placeholder="请选择几人间"
clearable
style="width: 100%">
<el-option
v-for="item in bedNumList"
: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="liveNum">
<el-input-number
v-model="form.liveNum"
:min="0"
placeholder="请输入已住人数"
style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="班号" prop="classNo">
<el-input v-model="form.classNo" placeholder="请输入班号" />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="班主任工号" prop="teacherNo">
<el-input v-model="form.teacherNo" placeholder="请输入班主任工号" />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="班主任姓名" prop="teacherRealName">
<el-input v-model="form.teacherRealName" placeholder="请输入班主任姓名" />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="校园补贴" prop="oddbMoney">
<el-input-number
v-model="form.oddbMoney"
:precision="2"
:min="0"
placeholder="请输入校园补贴"
style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="消费金额" prop="costMoney">
<el-input-number
v-model="form.costMoney"
:precision="2"
: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="WaterDetailFormDialog">
import { ref, reactive, nextTick, onMounted } from 'vue'
import { useMessage } from '/@/hooks/message'
import { addObj, putObj } from '/@/api/stuwork/waterdetail'
import { getBuildingList } from '/@/api/stuwork/dormbuilding'
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') // add 或 edit
const buildingList = ref<any[]>([])
const bedNumList = ref<any[]>([])
// 提交表单数据
const form = reactive({
id: '',
buildNo: '',
roomNo: '',
bedNum: '',
liveNum: 0,
classNo: '',
teacherNo: '',
teacherRealName: '',
oddbMoney: 0,
costMoney: 0
})
// 定义校验规则
const dataRules = {
buildNo: [
{ required: true, message: '请选择楼号', trigger: 'change' }
],
roomNo: [
{ required: true, message: '请输入宿舍号', trigger: 'blur' }
],
bedNum: [
{ required: true, message: '请选择床位数', trigger: 'change' }
],
liveNum: [
{ required: true, message: '请输入已住人数', trigger: 'blur' },
{ type: 'number', min: 0, message: '已住人数必须大于等于0', trigger: 'blur' }
]
}
// 打开弹窗
const openDialog = async (type: string = 'add', row?: any) => {
visible.value = true
operType.value = type
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields()
form.id = ''
form.buildNo = ''
form.roomNo = ''
form.bedNum = ''
form.liveNum = 0
form.classNo = ''
form.teacherNo = ''
form.teacherRealName = ''
form.oddbMoney = 0
form.costMoney = 0
// 编辑时填充数据
if (type === 'edit' && row) {
form.id = row.id
form.buildNo = row.buildNo || ''
form.roomNo = row.roomNo || ''
form.bedNum = row.bedNum || ''
form.liveNum = row.liveNum || 0
form.classNo = row.classNo || ''
form.teacherNo = row.teacherNo || ''
form.teacherRealName = row.teacherRealName || ''
form.oddbMoney = row.oddbMoney || 0
form.costMoney = row.costMoney || 0
}
})
}
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
loading.value = true
try {
const submitData: any = {
buildNo: form.buildNo,
roomNo: form.roomNo,
bedNum: form.bedNum,
liveNum: form.liveNum,
classNo: form.classNo,
teacherNo: form.teacherNo,
teacherRealName: form.teacherRealName,
oddbMoney: form.oddbMoney,
costMoney: form.costMoney
}
if (operType.value === 'add') {
await addObj(submitData)
useMessage().success('新增成功')
} else {
submitData.id = form.id
await putObj(submitData)
useMessage().success('编辑成功')
}
visible.value = false
emit('refresh')
} catch (err: any) {
useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败'))
} finally {
loading.value = false
}
})
}
// 获取楼号列表
const getBuildingListData = async () => {
try {
const res = await getBuildingList()
if (res.data) {
buildingList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取楼号列表失败', err)
buildingList.value = []
}
}
// 获取几人间字典
const getBedNumDict = async () => {
try {
const res = await getDicts('room_stu_num')
if (res.data) {
bedNumList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取几人间字典失败', err)
bedNumList.value = []
}
}
// 初始化
onMounted(() => {
getBuildingListData()
getBedNumDict()
})
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View File

@@ -0,0 +1,335 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<el-row v-show="showSearch">
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="可用余额" prop="effectiveMoney">
<el-input-number
v-model="searchForm.effectiveMoney"
placeholder="可用余额大于"
:precision="2"
:min="0"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="已住人数" prop="isLiveNum">
<el-select
v-model="searchForm.isLiveNum"
placeholder="请选择"
clearable
style="width: 200px">
<el-option label="大于0" :value="true" />
<el-option label="等于0" :value="false" />
</el-select>
</el-form-item>
<el-form-item label="楼号" prop="buildNo">
<el-select
v-model="searchForm.buildNo"
placeholder="请选择楼号"
clearable
filterable
style="width: 200px">
<el-option
v-for="item in buildingList"
:key="item.buildingNo"
:label="item.buildingNo"
:value="item.buildingNo">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="宿舍号" prop="roomNo">
<el-input
v-model="searchForm.roomNo"
placeholder="请输入宿舍号"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</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="FolderAdd"
type="primary"
class="ml10"
@click="formDialogRef.openDialog()">
</el-button>
<el-button
icon="Download"
type="success"
class="ml10"
@click="handleExport">
</el-button>
<el-button
icon="Setting"
type="warning"
class="ml10"
@click="handleInitWaterOrder">
初始化本期水电补贴
</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"
@sort-change="sortChangeHandle">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="buildNo" label="楼号" show-overflow-tooltip align="center" />
<el-table-column prop="roomNo" label="宿舍号" show-overflow-tooltip align="center" />
<el-table-column prop="bedNum" label="几人间" show-overflow-tooltip align="center" />
<el-table-column prop="liveNum" label="已住人数" show-overflow-tooltip align="center" />
<el-table-column prop="oddbMoney" label="校园补贴" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.oddbMoney ? Number(scope.row.oddbMoney).toFixed(2) : '0.00' }}</span>
</template>
</el-table-column>
<el-table-column prop="rechargeMoney" label="充值金额" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.rechargeMoney ? Number(scope.row.rechargeMoney).toFixed(2) : '0.00' }}</span>
</template>
</el-table-column>
<el-table-column prop="costMoney" label="消费金额" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ scope.row.costMoney ? Number(scope.row.costMoney).toFixed(2) : '0.00' }}</span>
</template>
</el-table-column>
<el-table-column prop="effectiveMoney" label="可用余额" show-overflow-tooltip align="center">
<template #default="scope">
<span :style="{ color: Number(scope.row.effectiveMoney) < 0 ? 'red' : '' }">
{{ scope.row.effectiveMoney ? Number(scope.row.effectiveMoney).toFixed(2) : '0.00' }}
</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="View"
text
type="info"
@click="handleViewDetail(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>
<!-- 表单弹窗 -->
<FormDialog ref="formDialogRef" @refresh="getDataList()" />
<!-- 明细弹窗 -->
<DetailDialog ref="detailDialogRef" />
<!-- 初始化水电补贴弹窗 -->
<el-dialog v-model="initDialogVisible" title="初始化本期水电补贴" :width="500" :close-on-click-modal="false" draggable>
<el-form ref="initFormRef" :model="initForm" :rules="initRules" label-width="120px">
<el-form-item label="补贴金额" prop="costMoney">
<el-input-number
v-model="initForm.costMoney"
:precision="2"
:min="0"
placeholder="请输入补贴金额"
style="width: 100%" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="initDialogVisible = false"> </el-button>
<el-button type="primary" @click="confirmInit" :loading="initLoading"> </el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts" name="WaterDetail">
import { reactive, ref, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, delObjs, initWaterOrder } from "/@/api/stuwork/waterdetail";
import { getBuildingList } from "/@/api/stuwork/dormbuilding";
import { useMessage, useMessageBox } from "/@/hooks/message";
import FormDialog from './form.vue';
import DetailDialog from './detail.vue';
// 定义变量内容
const searchFormRef = ref()
const formDialogRef = ref()
const detailDialogRef = ref()
const initFormRef = ref()
const showSearch = ref(true)
const buildingList = ref<any[]>([])
const initDialogVisible = ref(false)
const initLoading = ref(false)
// 搜索表单
const searchForm = reactive({
effectiveMoney: undefined as number | undefined,
isLiveNum: undefined as boolean | undefined,
buildNo: '',
roomNo: ''
})
// 初始化表单
const initForm = reactive({
costMoney: 0
})
// 初始化表单验证规则
const initRules = {
costMoney: [
{ required: true, message: '请输入补贴金额', trigger: 'blur' },
{ type: 'number', min: 0, message: '补贴金额必须大于等于0', trigger: 'blur' }
]
}
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: fetchList,
props: {
item: 'records',
totalCount: 'total'
},
createdIsNeed: true
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
tableStyle
} = useTable(state)
// 查询
const handleSearch = () => {
getDataList()
}
// 重置
const handleReset = () => {
searchFormRef.value?.formRef?.resetFields()
searchForm.effectiveMoney = undefined
searchForm.isLiveNum = undefined
searchForm.buildNo = ''
searchForm.roomNo = ''
getDataList()
}
// 编辑
const handleEdit = (row: any) => {
formDialogRef.value.openDialog('edit', row)
}
// 查看明细
const handleViewDetail = (row: any) => {
detailDialogRef.value.openDialog(row.roomNo)
}
// 删除
const handleDelete = async (row: any) => {
try {
await useMessageBox().confirm('确定要删除该记录吗?')
await delObjs([row.id])
useMessage().success('删除成功')
getDataList()
} catch (err: any) {
if (err !== 'cancel') {
useMessage().error(err.msg || '删除失败')
}
}
}
// 导出
const handleExport = () => {
// TODO: 实现导出功能
useMessage().warning('导出功能开发中')
}
// 初始化本期水电补贴
const handleInitWaterOrder = () => {
initDialogVisible.value = true
initForm.costMoney = 0
}
// 确认初始化
const confirmInit = async () => {
if (!initFormRef.value) return
await initFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
initLoading.value = true
try {
await initWaterOrder({ costMoney: initForm.costMoney })
useMessage().success('初始化成功')
initDialogVisible.value = false
getDataList()
} catch (err: any) {
useMessage().error(err.msg || '初始化失败')
} finally {
initLoading.value = false
}
})
}
// 获取楼号列表
const getBuildingListData = async () => {
try {
const res = await getBuildingList()
if (res.data) {
buildingList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取楼号列表失败', err)
buildingList.value = []
}
}
// 初始化
onMounted(() => {
getBuildingListData()
})
</script>

View File

@@ -0,0 +1,262 @@
<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="120px" v-loading="loading">
<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-form-item label="学年" prop="year">
<el-select
v-model="form.year"
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-form-item label="学期" prop="period">
<el-select
v-model="form.period"
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-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-form-item label="金额" prop="money">
<el-input-number
v-model="form.money"
:precision="2"
:min="0"
placeholder="请输入金额"
style="width: 100%" />
</el-form-item>
</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="WaterOrderFormDialog">
import { ref, reactive, nextTick, onMounted } from 'vue'
import { useMessage } from '/@/hooks/message'
import { addObj, putObj, getObj, getRoomList } from '/@/api/stuwork/waterorder'
import { queryAllSchoolYear } from '/@/api/basic/basicyear'
import { getDicts } from '/@/api/admin/dict'
const emit = defineEmits(['refresh'])
// 定义变量内容
const dataFormRef = ref()
const visible = ref(false)
const loading = ref(false)
const operType = ref('add') // add 或 edit
const schoolYearList = ref<any[]>([])
const schoolTermList = ref<any[]>([])
const typeList = ref<any[]>([])
const roomList = ref<any[]>([])
// 提交表单数据
const form = reactive({
id: '',
roomNo: '',
year: '',
period: '',
type: '',
money: 0
})
// 定义校验规则
const dataRules = {
roomNo: [
{ required: true, message: '请选择宿舍号', trigger: 'change' }
],
year: [
{ required: true, message: '请选择学年', trigger: 'change' }
],
period: [
{ required: true, message: '请选择学期', trigger: 'change' }
],
type: [
{ required: true, message: '请选择类型', trigger: 'change' }
],
money: [
{ required: true, message: '请输入金额', trigger: 'blur' },
{ type: 'number', min: 0, message: '金额必须大于等于0', 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.year = ''
form.period = ''
form.type = ''
form.money = 0
// 编辑时填充数据
if (type === 'edit' && row) {
form.id = row.id
form.roomNo = row.roomNo || ''
form.year = row.year || ''
form.period = row.period || ''
form.type = row.type || ''
form.money = row.money || 0
}
})
}
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return
loading.value = true
try {
const submitData: any = {
roomNo: form.roomNo,
year: form.year,
period: form.period,
type: form.type,
money: form.money
}
if (operType.value === 'add') {
await addObj(submitData)
useMessage().success('新增成功')
} else {
submitData.id = form.id
await putObj(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) {
schoolYearList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取学年列表失败', err)
schoolYearList.value = []
}
}
// 获取学期字典
const getSchoolTermDict = async () => {
try {
const res = await getDicts('school_term')
if (res.data) {
schoolTermList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取学期字典失败', err)
schoolTermList.value = []
}
}
// 获取类型字典
const getTypeDict = async () => {
try {
const res = await getDicts('dorm_water_source_type')
if (res.data) {
typeList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取类型字典失败', err)
typeList.value = []
}
}
// 获取宿舍号列表
const getRoomListData = async () => {
try {
const res = await getRoomList()
if (res.data) {
roomList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取宿舍号列表失败', err)
roomList.value = []
}
}
// 初始化
onMounted(() => {
getSchoolYearList()
getSchoolTermDict()
getTypeDict()
getRoomListData()
})
// 暴露方法给父组件
defineExpose({
openDialog
})
</script>

View File

@@ -0,0 +1,370 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<el-row v-show="showSearch">
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="宿舍号" prop="roomNo">
<el-input
v-model="searchForm.roomNo"
placeholder="请输入宿舍号"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="学年" prop="year">
<el-select
v-model="searchForm.year"
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="period">
<el-select
v-model="searchForm.period"
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="handleSearch">查询</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="FolderAdd"
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"
@sort-change="sortChangeHandle">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="roomNo" label="宿舍号" show-overflow-tooltip align="center" />
<el-table-column prop="year" label="学年" show-overflow-tooltip align="center" />
<el-table-column prop="period" label="学期" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ formatSchoolTerm(scope.row.period) }}</span>
</template>
</el-table-column>
<el-table-column prop="orderNum" 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="paymentCode" label="充值类型" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ formatPaymentType(scope.row.paymentCode) }}</span>
</template>
</el-table-column>
<el-table-column prop="money" label="金额" show-overflow-tooltip align="center" />
<el-table-column prop="chargeAccount" label="充值人的账户" show-overflow-tooltip align="center" />
<el-table-column prop="chargeRealname" label="充值人的真实姓名" show-overflow-tooltip align="center" />
<el-table-column prop="chargeState" label="充值结果" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ formatChargeState(scope.row.chargeState) }}</span>
</template>
</el-table-column>
<el-table-column prop="state" label="状态" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ formatState(scope.row.state) }}</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>
<!-- 表单弹窗 -->
<FormDialog ref="formDialogRef" @refresh="getDataList()" />
</div>
</template>
<script setup lang="ts" name="WaterOrder">
import { reactive, ref, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList } from "/@/api/stuwork/waterorder";
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
import { getDicts } from "/@/api/admin/dict";
import { useMessage, useMessageBox } from "/@/hooks/message";
import FormDialog from './form.vue';
// 定义变量内容
const searchFormRef = ref()
const formDialogRef = ref()
const showSearch = ref(true)
const schoolYearList = ref<any[]>([])
const schoolTermList = ref<any[]>([])
const typeList = ref<any[]>([])
const paymentTypeList = ref<any[]>([])
const chargeStateList = ref<any[]>([])
const stateList = ref<any[]>([])
// 搜索表单
const searchForm = reactive({
roomNo: '',
year: '',
period: ''
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: fetchList,
props: {
item: 'records',
totalCount: 'total'
},
createdIsNeed: true
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
tableStyle
} = useTable(state)
// 查询
const handleSearch = () => {
getDataList()
}
// 重置
const handleReset = () => {
searchFormRef.value?.formRef?.resetFields()
searchForm.roomNo = ''
searchForm.year = ''
searchForm.period = ''
getDataList()
}
// 编辑
const handleEdit = (row: any) => {
formDialogRef.value.openDialog('edit', row)
}
// 删除
const handleDelete = async (row: any) => {
try {
await useMessageBox().confirm('确定要删除该记录吗?')
const { delObjs } = await import("/@/api/stuwork/waterorder")
await delObjs([row.id])
useMessage().success('删除成功')
getDataList()
} catch (err: any) {
if (err !== 'cancel') {
useMessage().error(err.msg || '删除失败')
}
}
}
// 格式化学期
const formatSchoolTerm = (value: string | number) => {
if (value === null || value === undefined || value === '') {
return '-'
}
const dictItem = schoolTermList.value.find(item => item.value == value)
return dictItem ? dictItem.label : value
}
// 格式化类型
const formatType = (value: string | number) => {
if (value === null || value === undefined || value === '') {
return '-'
}
const dictItem = typeList.value.find(item => item.value == value)
return dictItem ? dictItem.label : value
}
// 格式化充值类型
const formatPaymentType = (value: string | number) => {
if (value === null || value === undefined || value === '') {
return '-'
}
const dictItem = paymentTypeList.value.find(item => item.value == value)
return dictItem ? dictItem.label : value
}
// 格式化充值结果
const formatChargeState = (value: string | number) => {
if (value === null || value === undefined || value === '') {
return '-'
}
const dictItem = chargeStateList.value.find(item => item.value == value)
return dictItem ? dictItem.label : value
}
// 格式化状态
const formatState = (value: string | number) => {
if (value === null || value === undefined || value === '') {
return '-'
}
const dictItem = stateList.value.find(item => item.value == value)
return dictItem ? dictItem.label : value
}
// 获取学年列表
const getSchoolYearList = async () => {
try {
const res = await queryAllSchoolYear()
if (res.data) {
schoolYearList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取学年列表失败', err)
schoolYearList.value = []
}
}
// 获取学期字典
const getSchoolTermDict = async () => {
try {
const res = await getDicts('school_term')
if (res.data) {
schoolTermList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取学期字典失败', err)
schoolTermList.value = []
}
}
// 获取类型字典
const getTypeDict = async () => {
try {
const res = await getDicts('dorm_water_source_type')
if (res.data) {
typeList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取类型字典失败', err)
typeList.value = []
}
}
// 获取充值类型字典
const getPaymentTypeDict = async () => {
try {
const res = await getDicts('dorm_water_payment_type')
if (res.data) {
paymentTypeList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取充值类型字典失败', err)
paymentTypeList.value = []
}
}
// 获取充值结果字典
const getChargeStateDict = async () => {
try {
const res = await getDicts('dorm_water_charge_state')
if (res.data) {
chargeStateList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取充值结果字典失败', err)
chargeStateList.value = []
}
}
// 获取状态字典
const getStateDict = async () => {
try {
const res = await getDicts('dorm_water_state')
if (res.data) {
stateList.value = Array.isArray(res.data) ? res.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code
})) : []
}
} catch (err) {
console.error('获取状态字典失败', err)
stateList.value = []
}
}
// 初始化
onMounted(() => {
getSchoolYearList()
getSchoolTermDict()
getTypeDict()
getPaymentTypeDict()
getChargeStateDict()
getStateDict()
})
</script>

View File

@@ -0,0 +1,287 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<el-row v-show="showSearch">
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="学院" prop="deptCode">
<el-select
v-model="searchForm.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="searchForm.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="source">
<el-select
v-model="searchForm.source"
placeholder="请选择来源"
clearable
style="width: 200px"
@change="handleSourceChange">
<el-option label="考勤记录" value="history" />
<el-option label="考勤" value="attendance" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</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="schoolYear" label="学年" show-overflow-tooltip align="center" />
<el-table-column prop="schoolTerm" label="学期" show-overflow-tooltip align="center" />
<el-table-column prop="deptName" label="系部名称" show-overflow-tooltip align="center" />
<el-table-column prop="classCode" label="班级代码" show-overflow-tooltip align="center" />
<el-table-column prop="classNo" label="班级简称" show-overflow-tooltip align="center" />
<el-table-column prop="classProName" label="班级规范名称" show-overflow-tooltip align="center" min-width="200" />
<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="attendanceType" label="考勤类型" show-overflow-tooltip align="center">
<template #default="scope">
<span>{{ formatAttendanceType(scope.row.attendanceType) }}</span>
</template>
</el-table-column>
<el-table-column
v-if="showRemarks"
prop="remarks"
label="落实情况"
show-overflow-tooltip
align="center"
min-width="150">
<template #default="scope">
<span>{{ scope.row.remarks || '-' }}</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>
<!-- 分页 -->
<pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
v-bind="state.pagination" />
</div>
</div>
</template>
<script setup lang="ts" name="WorkStudyAttendance">
import { reactive, ref, onMounted } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList, queryHistoryList } from "/@/api/stuwork/workstudyattendance";
import { getDeptList } from "/@/api/basic/basicclass";
import { getClassListByRole } from "/@/api/basic/basicclass";
import { useMessage } from "/@/hooks/message";
// 定义变量内容
const searchFormRef = ref()
const showSearch = ref(true)
const deptList = ref<any[]>([])
const classList = ref<any[]>([])
const showRemarks = ref(false) // 控制落实情况列的显示
// 搜索表单
const searchForm = reactive({
deptCode: '',
classCode: '',
source: '' // 来源选择:考勤记录、考勤
})
// 配置 useTable
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: fetchList,
props: {
item: 'tableData.records',
totalCount: 'tableData.total'
},
createdIsNeed: true
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
tableStyle
} = useTable(state)
// 格式化考勤类型
const formatAttendanceType = (value: string | number) => {
if (value === '1' || value === 1) return '到岗'
if (value === '2' || value === 2) return '未到岗'
if (value === '3' || value === 3) return '请假'
return '-'
}
// 学院变化时更新班级列表
const handleDeptChange = () => {
searchForm.classCode = ''
getClassListData()
}
// 来源选择变化
const handleSourceChange = async (value: string) => {
if (value === 'history') {
// 选择考勤记录时,显示落实情况列
showRemarks.value = true
// 查询考勤记录(不强制要求学院和班级)
try {
state.loading = true
const params: any = {}
if (searchForm.deptCode) {
params.deptCode = searchForm.deptCode
}
if (searchForm.classCode) {
params.classCode = searchForm.classCode
}
const res = await queryHistoryList(params)
if (res.data && Array.isArray(res.data)) {
state.dataList = res.data
if (state.pagination) {
state.pagination.total = res.data.length
}
} else {
state.dataList = []
if (state.pagination) {
state.pagination.total = 0
}
}
} catch (err: any) {
useMessage().error(err.msg || '查询考勤记录失败')
state.dataList = []
if (state.pagination) {
state.pagination.total = 0
}
} finally {
state.loading = false
}
} else if (value === 'attendance') {
// 选择考勤时,不显示落实情况列,使用普通列表接口
showRemarks.value = false
getDataList()
} else {
// 清空选择时,不显示落实情况列
showRemarks.value = false
getDataList()
}
}
// 查询
const handleSearch = () => {
if (searchForm.source === 'history') {
handleSourceChange('history')
} else {
showRemarks.value = false
getDataList()
}
}
// 重置
const handleReset = () => {
searchFormRef.value?.resetFields()
searchForm.deptCode = ''
searchForm.classCode = ''
searchForm.source = ''
showRemarks.value = false
getDataList()
}
// 查看详情
const handleView = (row: any) => {
useMessage().warning('查看详情功能待实现')
console.log('查看详情', row)
}
// 获取学院列表
const getDeptListData = async () => {
try {
const res = await getDeptList()
if (res.data) {
deptList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取学院列表失败', err)
deptList.value = []
}
}
// 获取班级列表
const getClassListData = async () => {
try {
const res = await getClassListByRole()
if (res.data) {
let list = Array.isArray(res.data) ? res.data : []
// 如果选择了学院,过滤班级列表
if (searchForm.deptCode) {
list = list.filter((item: any) => item.deptCode === searchForm.deptCode)
}
classList.value = list
}
} catch (err) {
console.error('获取班级列表失败', err)
classList.value = []
}
}
// 初始化
onMounted(() => {
getDeptListData()
getClassListData()
})
</script>