Ferat
This commit is contained in:
61818
docs/默认模块.openapi.json
61818
docs/默认模块.openapi.json
File diff suppressed because one or more lines are too long
@@ -23,7 +23,9 @@ export function getDictsByTypes(types: string[]) {
|
||||
return request({
|
||||
url: '/admin/dict/item/typeList',
|
||||
method: 'post',
|
||||
data: types,
|
||||
data: {
|
||||
typeList: types,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -165,6 +167,8 @@ export function queryDictByTypeList(types: string[]) {
|
||||
return request({
|
||||
url: '/admin/dict/queryDictByTypeList',
|
||||
method: 'post',
|
||||
data: types,
|
||||
data: {
|
||||
typeList: types,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取学生证件照列表(分页)
|
||||
* 获取学生证件照列表
|
||||
* @param query
|
||||
*/
|
||||
export const fetchList = (query?: any) => {
|
||||
return request({
|
||||
url: '/basic/basicstudent/avatar/page',
|
||||
url: '/basic/basicstudent/avatar/list',
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ import request from '/@/utils/request';
|
||||
*/
|
||||
export const fetchList = (query: any) => {
|
||||
return request({
|
||||
url: '/stuwork/classhygienedaily/page',
|
||||
url: '/stuwork/classhygienedailyanalysis/queryClassHygieneDailyAnalysis',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
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 }
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
24
src/api/stuwork/dormbuildingmanger.ts
Normal file
24
src/api/stuwork/dormbuildingmanger.ts
Normal 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
|
||||
});
|
||||
};
|
||||
|
||||
57
src/api/stuwork/dormhygienedaily.ts
Normal file
57
src/api/stuwork/dormhygienedaily.ts
Normal 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 }
|
||||
});
|
||||
};
|
||||
|
||||
57
src/api/stuwork/dormreform.ts
Normal file
57
src/api/stuwork/dormreform.ts
Normal 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 }
|
||||
});
|
||||
};
|
||||
|
||||
89
src/api/stuwork/dormroom.ts
Normal file
89
src/api/stuwork/dormroom.ts
Normal 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 }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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 }
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
14
src/api/stuwork/pendingwork.ts
Normal file
14
src/api/stuwork/pendingwork.ts
Normal 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
|
||||
});
|
||||
};
|
||||
|
||||
46
src/api/stuwork/stuworkstudyalternate.ts
Normal file
46
src/api/stuwork/stuworkstudyalternate.ts
Normal 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
|
||||
});
|
||||
};
|
||||
|
||||
57
src/api/stuwork/waterdetail.ts
Normal file
57
src/api/stuwork/waterdetail.ts
Normal 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
|
||||
});
|
||||
};
|
||||
|
||||
14
src/api/stuwork/watermonthreport.ts
Normal file
14
src/api/stuwork/watermonthreport.ts
Normal 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 }
|
||||
});
|
||||
};
|
||||
|
||||
67
src/api/stuwork/waterorder.ts
Normal file
67
src/api/stuwork/waterorder.ts
Normal 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'
|
||||
});
|
||||
};
|
||||
|
||||
35
src/api/stuwork/workstudyattendance.ts
Normal file
35
src/api/stuwork/workstudyattendance.ts
Normal 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
|
||||
});
|
||||
};
|
||||
|
||||
@@ -99,14 +99,19 @@ function initHandle() {
|
||||
|
||||
/**
|
||||
* 点击某一节点时触发的事件,更新当前的选中值和展开状态。
|
||||
* @param {Object} data - 被点击的节点数据
|
||||
* @param {Object} node - 被点击的节点对象
|
||||
*/
|
||||
function handleNodeClick(node) {
|
||||
valueTitle.value = node[props.objMap.label];
|
||||
valueId.value = node[props.objMap.value];
|
||||
defaultExpandedKey.value = [];
|
||||
proxy.$refs.treeSelect.blur();
|
||||
selectFilterData('');
|
||||
function handleNodeClick(data, node) {
|
||||
// el-tree 的 node-click 事件传递 (data, node) 两个参数
|
||||
const nodeData = data || (node && node.data) || node;
|
||||
if (nodeData) {
|
||||
valueTitle.value = nodeData[props.objMap.label] || nodeData[props.objMap.value] || '';
|
||||
valueId.value = nodeData[props.objMap.value] || '';
|
||||
defaultExpandedKey.value = [];
|
||||
proxy.$refs.treeSelect.blur();
|
||||
selectFilterData('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -361,8 +361,8 @@
|
||||
<script setup lang="ts" name="BasicStudent">
|
||||
import { ref, reactive, defineAsyncComponent, computed, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList } from "/@/api/basic/basicstudentinfo";
|
||||
import {
|
||||
fetchList,
|
||||
delObj,
|
||||
exportStudentData,
|
||||
applyInternship,
|
||||
@@ -477,63 +477,27 @@ const handleSelectionChange = (selection: any[]) => {
|
||||
|
||||
// 学生信息导出
|
||||
const handleExportStudent = async () => {
|
||||
try {
|
||||
await exportStudentData(searchForm)
|
||||
useMessage().success('导出成功')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 申请顶岗
|
||||
const handleApplyInternship = async () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
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 || '申请失败')
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 导出头像
|
||||
const handleExportAvatar = async () => {
|
||||
try {
|
||||
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 || '导出失败')
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 批量打印
|
||||
const handleBatchPrint = async () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
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 || '打印准备失败')
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 段段清证书导入
|
||||
const handleImportCertificate = () => {
|
||||
importCertificateDialogVisible.value = true
|
||||
fileList.value = []
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 上传相关
|
||||
@@ -579,111 +543,47 @@ const handleUploadError = (err: any) => {
|
||||
|
||||
// 学籍卡导出
|
||||
const handleExportStudentCard = async () => {
|
||||
try {
|
||||
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 || '导出失败')
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 证书导出
|
||||
const handleExportCertificate = async () => {
|
||||
try {
|
||||
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 || '导出失败')
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 简单信息维护
|
||||
const handleSimpleEdit = (row: any) => {
|
||||
if (simpleEditDialogRef.value) {
|
||||
simpleEditDialogRef.value.openDialog(row)
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const handleViewDetail = (row: any) => {
|
||||
if (detailDialogRef.value) {
|
||||
detailDialogRef.value.openDialog(row.id)
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 打印证件照
|
||||
const handlePrintPhoto = async (row: any) => {
|
||||
try {
|
||||
await prePrint(row.stuNo)
|
||||
useMessage().success('打印准备成功')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '打印准备失败')
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 重置密码
|
||||
const handleResetPassword = async (row: any) => {
|
||||
try {
|
||||
await useMessageBox().confirm('确定要重置该学生的密码吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
await resetPassWord({ stuNo: row.stuNo })
|
||||
useMessage().success('重置成功')
|
||||
} catch (err: any) {
|
||||
if (err !== 'cancel') {
|
||||
useMessage().error(err.msg || '重置失败')
|
||||
}
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 设为班干部
|
||||
const handleSetLeader = async (row: any) => {
|
||||
try {
|
||||
await editIsleader({ id: row.id, isClassLeader: 1 })
|
||||
useMessage().success('设置成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '设置失败')
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 取消班干部
|
||||
const handleCancelLeader = async (row: any) => {
|
||||
try {
|
||||
await editIsleader({ id: row.id, isClassLeader: 0 })
|
||||
useMessage().success('取消成功')
|
||||
getDataList()
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '取消失败')
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 禁止进出
|
||||
const handleForbidInout = async (row: any) => {
|
||||
try {
|
||||
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 || '操作失败')
|
||||
}
|
||||
}
|
||||
useMessage().warning('功能开发中')
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
|
||||
@@ -53,9 +53,9 @@
|
||||
<el-table-column prop="headImg" label="头像" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-image
|
||||
v-if="scope.row.headImg"
|
||||
:src="scope.row.headImg"
|
||||
:preview-src-list="[scope.row.headImg]"
|
||||
v-if="scope.row.headImg || scope.row.imageUrl || scope.row.qrCode"
|
||||
:src="scope.row.headImg || scope.row.imageUrl || scope.row.qrCode"
|
||||
:preview-src-list="[scope.row.headImg || scope.row.imageUrl || scope.row.qrCode]"
|
||||
fit="cover"
|
||||
style="width: 80px; height: 100px; cursor: pointer;"
|
||||
lazy>
|
||||
@@ -96,10 +96,44 @@ const searchForm = reactive({
|
||||
classCode: ''
|
||||
})
|
||||
|
||||
// 配置 useTable
|
||||
// 配置 useTable - 接口返回的数据结构是 { classes: [], students: [] }
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
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: {
|
||||
item: 'records',
|
||||
totalCount: 'total'
|
||||
|
||||
@@ -29,21 +29,6 @@
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</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>
|
||||
@@ -166,7 +151,6 @@ import { ref, reactive, defineAsyncComponent, onMounted, computed } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList } from "/@/api/stuwork/classhygienedailyanalysis";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass'
|
||||
import { getBuildingList } from '/@/api/stuwork/dormbuilding'
|
||||
|
||||
// 定义变量内容
|
||||
@@ -174,7 +158,6 @@ const searchFormRef = ref()
|
||||
const scoreFormRef = ref()
|
||||
// 搜索变量
|
||||
const showSearch = ref(true)
|
||||
const classList = ref<any[]>([])
|
||||
const buildingList = ref<any[]>([])
|
||||
const scoreDialogVisible = ref(false)
|
||||
const scoreDialogTitle = ref('加分')
|
||||
@@ -192,8 +175,7 @@ const scoreForm = reactive({
|
||||
// 搜索表单
|
||||
const searchForm = reactive({
|
||||
buildingNo: '',
|
||||
month: '',
|
||||
classCode: ''
|
||||
month: ''
|
||||
})
|
||||
|
||||
// 计算月份的天数列
|
||||
@@ -206,31 +188,77 @@ const dayColumns = computed(() => {
|
||||
return Array.from({ length: daysInMonth }, (_, i) => i + 1)
|
||||
})
|
||||
|
||||
// 配置 useTable - 需要将月份转换为开始和结束时间,且不传分页参数
|
||||
// 配置 useTable - 接口参数为 buildingNo 和 month(数组格式)
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: searchForm,
|
||||
isPage: false, // 接口不支持分页
|
||||
pageList: async (queryParams: any) => {
|
||||
// 如果选择了月份,转换为开始和结束时间
|
||||
const params: any = {}
|
||||
|
||||
// 如果选择了月份,转换为开始和结束时间
|
||||
// 接口文档要求 buildingNo 和 month 都是数组格式
|
||||
if (searchForm.buildingNo) {
|
||||
params.buildingNo = Array.isArray(searchForm.buildingNo) ? searchForm.buildingNo : [searchForm.buildingNo]
|
||||
}
|
||||
if (searchForm.month) {
|
||||
const [year, month] = searchForm.month.split('-').map(Number)
|
||||
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')}`
|
||||
params.month = Array.isArray(searchForm.month) ? searchForm.month : [searchForm.month]
|
||||
}
|
||||
|
||||
// 如果选择了班号,转换为数组格式(接口要求classCode是数组)
|
||||
if (searchForm.classCode) {
|
||||
params.classCode = Array.isArray(searchForm.classCode) ? searchForm.classCode : [searchForm.classCode]
|
||||
const res = await fetchList(params)
|
||||
|
||||
// 接口返回的数据结构:数组,每个元素包含日期字段(如 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参数,可能需要通过其他方式处理
|
||||
// 暂时不传递buildingNo,如果需要可以后续添加
|
||||
// 处理数据:将日期字段转换为 day1, day2 等格式,方便表格显示
|
||||
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 await fetchList(params)
|
||||
return {
|
||||
...res,
|
||||
data: processedData
|
||||
}
|
||||
},
|
||||
props: {
|
||||
item: 'records',
|
||||
@@ -262,7 +290,6 @@ const handleReset = () => {
|
||||
searchFormRef.value?.resetFields()
|
||||
searchForm.buildingNo = ''
|
||||
searchForm.month = ''
|
||||
searchForm.classCode = ''
|
||||
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 () => {
|
||||
try {
|
||||
@@ -352,7 +366,6 @@ const getBuildingListData = async () => {
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getClassListData()
|
||||
getBuildingListData()
|
||||
})
|
||||
</script>
|
||||
|
||||
182
src/views/stuwork/dormbuilding/emptyRoomDialog.vue
Normal file
182
src/views/stuwork/dormbuilding/emptyRoomDialog.vue
Normal 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>
|
||||
|
||||
126
src/views/stuwork/dormbuilding/form.vue
Normal file
126
src/views/stuwork/dormbuilding/form.vue
Normal 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>
|
||||
|
||||
251
src/views/stuwork/dormbuilding/index.vue
Normal file
251
src/views/stuwork/dormbuilding/index.vue
Normal 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>
|
||||
77
src/views/stuwork/dormbuildingmanger/index.vue
Normal file
77
src/views/stuwork/dormbuildingmanger/index.vue
Normal 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>
|
||||
|
||||
173
src/views/stuwork/dormhygienedaily/form.vue
Normal file
173
src/views/stuwork/dormhygienedaily/form.vue
Normal 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>
|
||||
|
||||
261
src/views/stuwork/dormhygienedaily/index.vue
Normal file
261
src/views/stuwork/dormhygienedaily/index.vue
Normal 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>
|
||||
131
src/views/stuwork/dormreform/form.vue
Normal file
131
src/views/stuwork/dormreform/form.vue
Normal 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>
|
||||
|
||||
309
src/views/stuwork/dormreform/index.vue
Normal file
309
src/views/stuwork/dormreform/index.vue
Normal 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>
|
||||
|
||||
237
src/views/stuwork/dormroom/form.vue
Normal file
237
src/views/stuwork/dormroom/form.vue
Normal 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>
|
||||
|
||||
379
src/views/stuwork/dormroom/index.vue
Normal file
379
src/views/stuwork/dormroom/index.vue
Normal 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>
|
||||
92
src/views/stuwork/dormroomstudent/dormabnormal.vue
Normal file
92
src/views/stuwork/dormroomstudent/dormabnormal.vue
Normal 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>
|
||||
|
||||
327
src/views/stuwork/dormroomstudent/form.vue
Normal file
327
src/views/stuwork/dormroomstudent/form.vue
Normal 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>
|
||||
|
||||
410
src/views/stuwork/dormroomstudent/index.vue
Normal file
410
src/views/stuwork/dormroomstudent/index.vue
Normal 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>
|
||||
|
||||
227
src/views/stuwork/dormroomstudent/transfer.vue
Normal file
227
src/views/stuwork/dormroomstudent/transfer.vue
Normal 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>
|
||||
|
||||
245
src/views/stuwork/dormroomstudentchange/index.vue
Normal file
245
src/views/stuwork/dormroomstudentchange/index.vue
Normal 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>
|
||||
|
||||
195
src/views/stuwork/pendingwork/index.vue
Normal file
195
src/views/stuwork/pendingwork/index.vue
Normal 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>
|
||||
|
||||
149
src/views/stuwork/stuworkstudyalternate/form.vue
Normal file
149
src/views/stuwork/stuworkstudyalternate/form.vue
Normal 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>
|
||||
|
||||
317
src/views/stuwork/stuworkstudyalternate/index.vue
Normal file
317
src/views/stuwork/stuworkstudyalternate/index.vue
Normal file
@@ -0,0 +1,317 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 搜索表单 -->
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="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>
|
||||
|
||||
211
src/views/stuwork/stuworkstudyalternate/teacher.vue
Normal file
211
src/views/stuwork/stuworkstudyalternate/teacher.vue
Normal 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>
|
||||
|
||||
114
src/views/stuwork/waterdetail/detail.vue
Normal file
114
src/views/stuwork/waterdetail/detail.vue
Normal 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>
|
||||
|
||||
279
src/views/stuwork/waterdetail/form.vue
Normal file
279
src/views/stuwork/waterdetail/form.vue
Normal 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>
|
||||
|
||||
335
src/views/stuwork/waterdetail/index.vue
Normal file
335
src/views/stuwork/waterdetail/index.vue
Normal 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>
|
||||
|
||||
262
src/views/stuwork/waterorder/form.vue
Normal file
262
src/views/stuwork/waterorder/form.vue
Normal 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>
|
||||
|
||||
370
src/views/stuwork/waterorder/index.vue
Normal file
370
src/views/stuwork/waterorder/index.vue
Normal 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>
|
||||
|
||||
287
src/views/stuwork/workstudyattendance/index.vue
Normal file
287
src/views/stuwork/workstudyattendance/index.vue
Normal 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>
|
||||
|
||||
Reference in New Issue
Block a user