diff --git a/src/api/basic/basicclass.ts b/src/api/basic/basicclass.ts index b8c0c05..7427c2a 100644 --- a/src/api/basic/basicclass.ts +++ b/src/api/basic/basicclass.ts @@ -76,13 +76,13 @@ export const delObj = (id: string | number) => { }; /** - * 更新 - * @param obj + * 更新(编辑) + * @param obj 含 id 及需修改字段,走接口文档 /edit 接口 */ export const putObj = (obj: any) => { return request({ - url: '/basic/basicclass', - method: 'put', + url: '/basic/basicclass/edit', + method: 'post', data: obj, }); }; diff --git a/src/api/stuwork/activityinfosub.ts b/src/api/stuwork/activityinfosub.ts index bcc4825..c7a8e8b 100644 --- a/src/api/stuwork/activityinfosub.ts +++ b/src/api/stuwork/activityinfosub.ts @@ -22,6 +22,19 @@ export const getActivityInfoList = () => { }); }; +/** + * 查看详情 - 根据活动ID获取活动子项目列表 + * 接口文档:GET /api/stuwork/activityinfosub/getActivityInfoSubList + * @param activityInfoId 活动信息ID + */ +export const getActivityInfoSubList = (activityInfoId: string) => { + return request({ + url: '/stuwork/activityinfosub/getActivityInfoSubList', + method: 'get', + params: { activityInfoId } + }); +}; + /** * 删除活动子项目 * @param ids diff --git a/src/api/stuwork/dormroomstudent.ts b/src/api/stuwork/dormroomstudent.ts index 3d4490e..bfa3e7a 100644 --- a/src/api/stuwork/dormroomstudent.ts +++ b/src/api/stuwork/dormroomstudent.ts @@ -103,3 +103,37 @@ export const fearchRoomStuNum = (roomNo: string) => { }); }; +/** + * 互换宿舍(文档:sourceSutNo / targetStuNO) + */ +export const exchangeRoom = (data: { sourceSutNo: string; targetStuNO: string }) => { + return request({ + url: '/stuwork/dormroomstudent/exchangeRoom', + method: 'post', + data + }); +}; + +/** + * 打印宿舍卡(按房间号获取打印数据) + */ +export const printDormRoomData = (roomNo: string) => { + return request({ + url: '/stuwork/dormroomstudent/printDormRoomData', + method: 'get', + params: { roomNo } + }); +}; + +/** + * 空 n 人宿舍导出 + */ +export const exportEmptyPeopleRoomExcel = (data?: any) => { + return request({ + url: '/stuwork/dormroomstudent/exportEmptyPeopleRoomExcel', + method: 'post', + data: data || {}, + responseType: 'blob' + }); +}; + diff --git a/src/api/stuwork/gradustu.ts b/src/api/stuwork/gradustu.ts new file mode 100644 index 0000000..41a069e --- /dev/null +++ b/src/api/stuwork/gradustu.ts @@ -0,0 +1,61 @@ +import request from '/@/utils/request' + +/** + * 分页查询毕业学生(毕业审核列表) + * 后端返回 data.dataList.records / data.dataList.total,此处归一为 data.records / data.total 供 useTable 使用 + * @param query current, size, graduYear, status, type, stuNo, realName, classCode, deptCode, ... + */ +export const fetchList = (query?: any) => { + return request({ + url: '/stuwork/stugraducheck/page', + method: 'get', + params: query + }).then((res: any) => { + const raw = res.data || {} + const dataList = raw.dataList || {} + return { + ...res, + data: { + records: dataList.records || [], + total: dataList.total ?? 0, + canExamConduct: raw.canExamConduct, + canExamScore: raw.canExamScore, + canExamSkill: raw.canExamSkill, + canExamStuPunish: raw.canExamStuPunish, + canExamBaseInfo: raw.canExamBaseInfo + } + } + }) +} + +/** + * 生成毕业生信息 + * @param data 如 { type: '0' } + */ +export const makeGraduStu = (data?: { type?: string }) => { + return request({ + url: '/stuwork/stugraducheck/makeGraduStu', + method: 'post', + data: data || { type: '0' } + }) +} + +/** + * 获取某年毕业生列表(用于统计页前端汇总,大 size 拉取) + * @param graduYear 毕业年份 + */ +export const fetchListForAnalyse = (graduYear: string | number) => { + return request({ + url: '/stuwork/stugraducheck/page', + method: 'get', + params: { + graduYear, + current: 1, + size: 9999 + } + }).then((res: any) => { + const raw = res.data || {} + const dataList = raw.dataList || {} + return (dataList.records || []) as any[] + }) +} diff --git a/src/api/stuwork/psychologicalcounselingduty.ts b/src/api/stuwork/psychologicalcounselingduty.ts new file mode 100644 index 0000000..d9a2ed9 --- /dev/null +++ b/src/api/stuwork/psychologicalcounselingduty.ts @@ -0,0 +1,73 @@ +import request from '/@/utils/request' + +/** + * 按月份返回值班表(列表) + * @param params year, month + */ +export const listByMonth = (params: { year: string | number; month: string | number }) => { + return request({ + url: '/stuwork/psychologicalcounselingduty/listByMonth', + method: 'get', + params + }) +} + +/** + * 后台获取某年某月值班表,回显到日历/列表 + * @param params year, month + */ +export const getDutyByMonth = (params: { year: string | number; month: string | number }) => { + return request({ + url: '/stuwork/psychologicalcounselingduty/getDutyByMonth', + method: 'get', + params + }) +} + +/** + * 通过 id 查询值班详情 + * @param id + */ +export const getDetail = (id: string) => { + return request({ + url: '/stuwork/psychologicalcounselingduty/detail', + method: 'get', + params: { id } + }) +} + +/** + * 新增/批量新增值班 + * @param list 每项 { date: 'YYYY-MM-DD', teacherUserName: '工号', weekType?: 'single'|'double' } + */ +export const saveDuty = (list: Array<{ date: string; teacherUserName: string; weekType?: string }>) => { + return request({ + url: '/stuwork/psychologicalcounselingduty/saveDuty', + method: 'post', + data: list + }) +} + +/** + * 一键清空某月值班 + * @param data { year, month } + */ +export const clearDuty = (data: { year: number; month: number }) => { + return request({ + url: '/stuwork/psychologicalcounselingduty/clearDuty', + method: 'post', + data + }) +} + +/** + * 清除单个值班(按日期) + * @param data { days: 'YYYY-MM-DD' } + */ +export const clearOneDuty = (data: { days: string }) => { + return request({ + url: '/stuwork/psychologicalcounselingduty/clearOneDuty', + method: 'post', + data + }) +} diff --git a/src/api/stuwork/psychologicalcounselingreservation.ts b/src/api/stuwork/psychologicalcounselingreservation.ts new file mode 100644 index 0000000..da7a725 --- /dev/null +++ b/src/api/stuwork/psychologicalcounselingreservation.ts @@ -0,0 +1,61 @@ +import request from '/@/utils/request' + +/** + * 分页查询预约记录 + * @param query current, size, stuNo, classNo, reservationTime, isHandle + */ +export const fetchList = (query?: any) => { + return request({ + url: '/stuwork/psychologicalcounselingreservation/page', + method: 'get', + params: query + }) +} + +/** + * 通过 id 查询预约记录详情 + * @param id + */ +export const getDetail = (id: string) => { + return request({ + url: '/stuwork/psychologicalcounselingreservation/detail', + method: 'get', + params: { id } + }) +} + +/** + * 新增预约记录 + * @param data teacherNo, reservationTime, classNo, stuNo, stuName, phone, remarks, realName?, isHandle? + */ +export const addObj = (data: any) => { + return request({ + url: '/stuwork/psychologicalcounselingreservation', + method: 'post', + data + }) +} + +/** + * 修改预约记录 + * @param data 含 id 及需修改字段 + */ +export const editObj = (data: any) => { + return request({ + url: '/stuwork/psychologicalcounselingreservation/edit', + method: 'post', + data + }) +} + +/** + * 通过 id 删除预约记录 + * @param ids id 数组 + */ +export const delObj = (ids: string[]) => { + return request({ + url: '/stuwork/psychologicalcounselingreservation/delete', + method: 'post', + data: ids + }) +} diff --git a/src/api/stuwork/psychologicalcounselingteacher.ts b/src/api/stuwork/psychologicalcounselingteacher.ts new file mode 100644 index 0000000..6af34c0 --- /dev/null +++ b/src/api/stuwork/psychologicalcounselingteacher.ts @@ -0,0 +1,71 @@ +import request from '/@/utils/request' + +/** + * 分页查询心理咨询预约师 + * @param query current, size, realName + */ +export const fetchList = (query?: any) => { + return request({ + url: '/stuwork/psychologicalcounselingteacher/page', + method: 'get', + params: query + }) +} + +/** + * 获取预约师列表(不分页) + */ +export const getList = () => { + return request({ + url: '/stuwork/psychologicalcounselingteacher/list', + method: 'get' + }) +} + +/** + * 通过 id 查询详情 + * @param id + */ +export const getDetail = (id: string) => { + return request({ + url: '/stuwork/psychologicalcounselingteacher/detail', + method: 'get', + params: { id } + }) +} + +/** + * 新增心理咨询预约师 + * @param data userName, realName, phone, remarks + */ +export const addObj = (data: any) => { + return request({ + url: '/stuwork/psychologicalcounselingteacher', + method: 'post', + data + }) +} + +/** + * 修改心理咨询预约师 + * @param data id, userName, realName, phone, remarks + */ +export const editObj = (data: any) => { + return request({ + url: '/stuwork/psychologicalcounselingteacher/edit', + method: 'post', + data + }) +} + +/** + * 通过 id 删除心理咨询预约师 + * @param ids id 数组 + */ +export const delObj = (ids: string[]) => { + return request({ + url: '/stuwork/psychologicalcounselingteacher/delete', + method: 'post', + data: ids + }) +} diff --git a/src/api/stuwork/stuconduct.ts b/src/api/stuwork/stuconduct.ts index a329a74..67293a9 100644 --- a/src/api/stuwork/stuconduct.ts +++ b/src/api/stuwork/stuconduct.ts @@ -36,6 +36,18 @@ export const getDetail = (id: string) => { }); }; +/** + * 通过学年学号查看详情(接口文档:GET /stuwork/stuconduct/queryDataByStuNo) + * @param params stuNo 学号, schoolYear 学年 + */ +export const queryDataByStuNo = (params: { stuNo: string; schoolYear: string }) => { + return request({ + url: '/stuwork/stuconduct/queryDataByStuNo', + method: 'get', + params + }); +}; + /** * 编辑操行考核 * @param data diff --git a/src/api/stuwork/stugraducheck.ts b/src/api/stuwork/stugraducheck.ts new file mode 100644 index 0000000..b877870 --- /dev/null +++ b/src/api/stuwork/stugraducheck.ts @@ -0,0 +1,25 @@ +import request from '/@/utils/request' + +/** + * 毕业学生名单 - 分页查询 + * 接口文档:GET /api/stuwork/stugraducheck/page + * 参数:current, size, graduYear, status, type, stuNo, realName, classCode, deptCode 等 + * 返回归一为 data.records / data.total 供 useTable 使用 + */ +export const fetchList = (query?: any) => { + return request({ + url: '/stuwork/stugraducheck/page', + method: 'get', + params: query + }).then((res: any) => { + const raw = res.data || {} + const dataList = raw.dataList || {} + return { + ...res, + data: { + records: dataList.records || [], + total: dataList.total ?? 0 + } + } + }) +} diff --git a/src/api/stuwork/stuturnover.ts b/src/api/stuwork/stuturnover.ts index fd48a9a..8a953da 100644 --- a/src/api/stuwork/stuturnover.ts +++ b/src/api/stuwork/stuturnover.ts @@ -60,6 +60,18 @@ export const delObj = (ids: string[]) => { }); }; +/** + * 撤销学籍异动 + * @param ids 异动记录ID列表 + */ +export const cancelObj = (ids: string[]) => { + return request({ + url: '/stuwork/stuturnover/cancel', + method: 'post', + data: ids + }); +}; + /** * 导出学籍异动 * @param query diff --git a/src/api/stuwork/teachclassroomassign.ts b/src/api/stuwork/teachclassroomassign.ts index d132acd..75275ad 100644 --- a/src/api/stuwork/teachclassroomassign.ts +++ b/src/api/stuwork/teachclassroomassign.ts @@ -12,3 +12,16 @@ export const getClassRoomByClassCode = (classCode: string | number) => { }); }; +/** + * 教室安排 + * 接口文档:POST /api/stuwork/teachclassroomassign/addClassRoomAssign + * @param data buildingNo 楼号, position 位置, classCode 班级代码 + */ +export const addClassRoomAssign = (data: { buildingNo?: string | number; position?: string; classCode?: string }) => { + return request({ + url: '/stuwork/teachclassroomassign/addClassRoomAssign', + method: 'post', + data, + }); +}; + diff --git a/src/hooks/table.ts b/src/hooks/table.ts index 1777d80..e112431 100644 --- a/src/hooks/table.ts +++ b/src/hooks/table.ts @@ -156,8 +156,10 @@ export function useTable(options?: BasicTableProps) { if (state.onLoaded) await state.onLoaded(state); if (state.onCascaded) await state.onCascaded(state); } catch (err: any) { - // 捕获异常并显示错误提示 - ElMessage.error(err.msg || err.data.msg); + // 全局拦截器已展示过错误时不再重复弹窗 + if (!err?._messageShown) { + ElMessage.error(err?.msg || err?.data?.msg || '请求失败'); + } } finally { // 结束加载数据,设置state.loading为false state.loading = false; diff --git a/src/utils/request.ts b/src/utils/request.ts index 3a25d38..dc86db0 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -97,9 +97,10 @@ service.interceptors.request.use( */ const handleResponse = (response: AxiosResponse) => { if (response.data.code === 1) { - // 业务错误,统一弹出错误提示 + // 业务错误,统一弹出错误提示(标记已展示,避免 hook/页面 catch 再次弹窗) if (response.data.msg) { useMessage().error(response.data.msg); + response.data._messageShown = true; } throw response.data; } diff --git a/src/views/basic/basicclass/form.vue b/src/views/basic/basicclass/form.vue index 4f1c204..e5130dc 100644 --- a/src/views/basic/basicclass/form.vue +++ b/src/views/basic/basicclass/form.vue @@ -204,7 +204,8 @@ const dataRules = ref({ { required: true, message: '学院不能为空', trigger: 'change' } ], classCode: [ - { required: true, message: '班级代码不能为空', trigger: 'blur' } + { required: true, message: '班级代码不能为空', trigger: 'blur' }, + { min: 4, message: '班级代码至少4位(班号取后4位)', trigger: 'blur' } ], classNo: [ { required: true, message: '班号不能为空', trigger: 'blur' } @@ -406,11 +407,11 @@ watch(() => form.enterDate, (newVal) => { } }) -// 监听班级代码,取后四位为班号 +// 监听班级代码,取后四位为班号(班级代码至少4位) watch(() => form.classCode, (newVal) => { if (newVal) { const length = newVal.length - if (length > 4) { + if (length >= 4) { // 只在新增模式下自动填充班号,编辑模式下如果班号为空才填充 if (!form.id || !form.classNo) { form.classNo = newVal.substring(length - 4, length) diff --git a/src/views/basic/basicclass/index.vue b/src/views/basic/basicclass/index.vue index 586420c..52ac5d7 100644 --- a/src/views/basic/basicclass/index.vue +++ b/src/views/basic/basicclass/index.vue @@ -196,7 +196,7 @@ - + - + @@ -281,7 +291,7 @@ import { reactive, ref, onMounted, computed, nextTick } from 'vue' import { useRoute } from 'vue-router' import { BasicTableProps, useTable } from "/@/hooks/table"; -import { fetchList, delObjs } from "/@/api/stuwork/dormroomstudent"; +import { fetchList, delObjs, exportEmptyPeopleRoomExcel } from "/@/api/stuwork/dormroomstudent"; import { getDeptList } from "/@/api/basic/basicclass"; import { getBuildingList } from "/@/api/stuwork/dormbuilding"; import { fetchDormRoomTreeList } from "/@/api/stuwork/dormroom"; @@ -289,6 +299,8 @@ import { useMessage, useMessageBox } from "/@/hooks/message"; import TableColumnControl from '/@/components/TableColumnControl/index.vue' import FormDialog from './form.vue'; import TransferDialog from './transfer.vue'; +import SwapDialog from './swap.vue'; +import PrintCardDialog from './printCard.vue'; import TreeSelect from '/@/components/TreeSelect/index.vue'; import { List, OfficeBuilding, House, Grid, UserFilled, Phone, CreditCard, Avatar, User, Setting, Menu, Search, Document } from '@element-plus/icons-vue' import { useTableColumnControl } from '/@/hooks/tableColumn' @@ -301,6 +313,8 @@ const route = useRoute() const formDialogRef = ref() const columnControlRef = ref() const transferDialogRef = ref() +const swapDialogRef = ref() +const printCardDialogRef = ref() const searchFormRef = ref() const showSearch = ref(true) const deptList = ref([]) @@ -425,29 +439,91 @@ const handleDormDataTypeChange = (dormdataType: string) => { getDormRoomTreeListData(dormdataType) } -// 打印宿舍卡 +// 打印宿舍卡(按房间号查询后打印) const handlePrintCard = () => { - useMessage().warning('功能开发中') + printCardDialogRef.value?.openDialog() } -// 宿舍互换 +// 宿舍互换(两名学生互换宿舍) const handleRoomSwap = () => { - useMessage().warning('功能开发中') + const query = { + deptCode: searchForm.deptCode, + buildingNo: searchForm.buildingNo, + gender: searchForm.gender, + roomNo: searchForm.roomNo || searchForm.roomNoInput, + classNo: searchForm.classNo, + stuNo: searchForm.stuNo, + realName: searchForm.realName + } + swapDialogRef.value?.openDialog(query) } -// 导出 -const handleExport = () => { - useMessage().warning('功能开发中') +// 导出:空 n 人宿舍导出(按当前筛选条件传参) +const handleExport = async () => { + try { + const params = { + deptCode: searchForm.deptCode, + buildingNo: searchForm.buildingNo, + gender: searchForm.gender, + dormdataType: searchForm.dormdataType, + roomNo: searchForm.roomNo || searchForm.roomNoInput, + classNo: searchForm.classNo, + stuNo: searchForm.stuNo, + realName: searchForm.realName + } + const res = await exportEmptyPeopleRoomExcel(params) + const blob = res instanceof Blob ? res : new Blob([res as BlobPart], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) + const url = window.URL.createObjectURL(blob) + const link = document.createElement('a') + link.href = url + link.download = `空宿舍导出_${Date.now()}.xlsx` + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + window.URL.revokeObjectURL(url) + useMessage().success('导出成功') + } catch (err: any) { + useMessage().error(err?.msg || '导出失败') + } } -// 名单导出 -const handleExportList = () => { - useMessage().warning('功能开发中') +// 名单导出:与导出共用空 n 人宿舍导出接口,文件名区分 +const handleExportList = async () => { + try { + const params = { + deptCode: searchForm.deptCode, + buildingNo: searchForm.buildingNo, + gender: searchForm.gender, + dormdataType: searchForm.dormdataType, + roomNo: searchForm.roomNo || searchForm.roomNoInput, + classNo: searchForm.classNo, + stuNo: searchForm.stuNo, + realName: searchForm.realName + } + const res = await exportEmptyPeopleRoomExcel(params) + const blob = res instanceof Blob ? res : new Blob([res as BlobPart], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) + const url = window.URL.createObjectURL(blob) + const link = document.createElement('a') + link.href = url + link.download = `住宿学生名单_${Date.now()}.xlsx` + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + window.URL.revokeObjectURL(url) + useMessage().success('导出成功') + } catch (err: any) { + useMessage().error(err?.msg || '导出失败') + } +} + +// 编辑(与转宿共用接口 edit,修改房间/床位/是否舍长) +const handleEdit = (row: any) => { + transferDialogRef.value?.openDialog(row) } // 转宿 const handleTransfer = (row: any) => { - transferDialogRef.value.openDialog(row) + transferDialogRef.value?.openDialog(row) } // 退宿 diff --git a/src/views/stuwork/dormroomstudent/printCard.vue b/src/views/stuwork/dormroomstudent/printCard.vue new file mode 100644 index 0000000..e51c1b3 --- /dev/null +++ b/src/views/stuwork/dormroomstudent/printCard.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/src/views/stuwork/dormroomstudent/swap.vue b/src/views/stuwork/dormroomstudent/swap.vue new file mode 100644 index 0000000..7311f0c --- /dev/null +++ b/src/views/stuwork/dormroomstudent/swap.vue @@ -0,0 +1,136 @@ + + + diff --git a/src/views/stuwork/dormroomstudent/transfer.vue b/src/views/stuwork/dormroomstudent/transfer.vue index d5161dd..6b521bc 100644 --- a/src/views/stuwork/dormroomstudent/transfer.vue +++ b/src/views/stuwork/dormroomstudent/transfer.vue @@ -41,9 +41,11 @@ style="width: 100%"> + :key="item.bedNo" + :value="item.bedNo"> + + {{ item.bedNo }}{{ item.haveStudent ? ' (有人)' : '' }} + @@ -95,7 +97,8 @@ const dataFormRef = ref() const visible = ref(false) const loading = ref(false) const roomList = ref([]) -const bedNoList = ref([]) +// 床位列表:支持 haveStudent 标记(true=有人,false=无人) +const bedNoList = ref>([]) // 提交表单数据 const form = reactive({ @@ -119,26 +122,33 @@ const dataRules = { ] } -// 房间号变化时获取床位号列表 +// 房间号变化时获取床位号列表(支持 haveStudent:true=有人,false=无人) const handleRoomChange = async (roomNo: string) => { if (!roomNo) { bedNoList.value = [] form.bedNo = '' return } - + + const toBedItem = (item: any): { bedNo: string; haveStudent: boolean } => { + if (typeof item === 'number' || typeof item === 'string') { + return { bedNo: String(item), haveStudent: false } + } + return { + bedNo: String(item?.bedNo ?? item?.value ?? item ?? ''), + haveStudent: !!(item && item.haveStudent === true) + } + } + 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) - }) + bedNoList.value = res.data.map(toBedItem).filter((b) => b.bedNo) } else if (res.data.bedNos && Array.isArray(res.data.bedNos)) { - bedNoList.value = res.data.bedNos.map((item: any) => String(item)) + bedNoList.value = res.data.bedNos.map((item: any) => + toBedItem(typeof item === 'object' ? item : { bedNo: String(item), haveStudent: false }) + ) } else { bedNoList.value = [] } @@ -157,20 +167,20 @@ const openDialog = async (row: any) => { visible.value = true // 重置表单数据 - nextTick(() => { - dataFormRef.value?.resetFields() - form.id = row.id || '' - form.roomNo = row.roomNo || '' + await 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 = [] + + // 如果有房间号,先拉取床位列表再回填床位号(避免 handleRoomChange 清空 bedNo) + if (form.roomNo) { + await handleRoomChange(form.roomNo) form.bedNo = row.bedNo || '' - form.stuNo = row.stuNo || '' - form.isLeader = row.isLeader || '0' - bedNoList.value = [] - - // 如果有房间号,获取床位号列表 - if (form.roomNo) { - handleRoomChange(form.roomNo) - } - }) + } } // 提交表单 @@ -224,3 +234,8 @@ defineExpose({ }) + diff --git a/src/views/stuwork/gradustu/analyse.vue b/src/views/stuwork/gradustu/analyse.vue new file mode 100644 index 0000000..d50addb --- /dev/null +++ b/src/views/stuwork/gradustu/analyse.vue @@ -0,0 +1,227 @@ + + + + + diff --git a/src/views/stuwork/gradustu/index.vue b/src/views/stuwork/gradustu/index.vue new file mode 100644 index 0000000..3fba8f7 --- /dev/null +++ b/src/views/stuwork/gradustu/index.vue @@ -0,0 +1,342 @@ + + + + + diff --git a/src/views/stuwork/psychologicalcounselingduty/form.vue b/src/views/stuwork/psychologicalcounselingduty/form.vue new file mode 100644 index 0000000..f3e4570 --- /dev/null +++ b/src/views/stuwork/psychologicalcounselingduty/form.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/src/views/stuwork/psychologicalcounselingduty/index.vue b/src/views/stuwork/psychologicalcounselingduty/index.vue new file mode 100644 index 0000000..48bc982 --- /dev/null +++ b/src/views/stuwork/psychologicalcounselingduty/index.vue @@ -0,0 +1,310 @@ + + + + + diff --git a/src/views/stuwork/psychologicalcounselingreservation/form.vue b/src/views/stuwork/psychologicalcounselingreservation/form.vue new file mode 100644 index 0000000..37a38e4 --- /dev/null +++ b/src/views/stuwork/psychologicalcounselingreservation/form.vue @@ -0,0 +1,309 @@ + + + + + diff --git a/src/views/stuwork/psychologicalcounselingreservation/index.vue b/src/views/stuwork/psychologicalcounselingreservation/index.vue new file mode 100644 index 0000000..a4e7bb7 --- /dev/null +++ b/src/views/stuwork/psychologicalcounselingreservation/index.vue @@ -0,0 +1,296 @@ + + + + + diff --git a/src/views/stuwork/psychologicalcounselingteacher/form.vue b/src/views/stuwork/psychologicalcounselingteacher/form.vue new file mode 100644 index 0000000..249a081 --- /dev/null +++ b/src/views/stuwork/psychologicalcounselingteacher/form.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/src/views/stuwork/psychologicalcounselingteacher/index.vue b/src/views/stuwork/psychologicalcounselingteacher/index.vue new file mode 100644 index 0000000..74807ff --- /dev/null +++ b/src/views/stuwork/psychologicalcounselingteacher/index.vue @@ -0,0 +1,244 @@ + + + + + diff --git a/src/views/stuwork/rewardclass/form.vue b/src/views/stuwork/rewardclass/form.vue index 0af1733..aafc884 100644 --- a/src/views/stuwork/rewardclass/form.vue +++ b/src/views/stuwork/rewardclass/form.vue @@ -31,12 +31,20 @@ - - + + filterable + style="width: 100%" + @change="handleRewardRuleChange"> + + @@ -67,6 +75,7 @@ import { ref, reactive, nextTick, onMounted } from 'vue' import { useMessage } from '/@/hooks/message' import { addObj, editObj, getDetail } from '/@/api/stuwork/rewardclass' import { getClassListByRole } from '/@/api/basic/basicclass' +import { getList as getRewardRuleList } from '/@/api/stuwork/rewardrule' const emit = defineEmits(['refresh']) @@ -76,6 +85,8 @@ const visible = ref(false) const loading = ref(false) const operType = ref('add') const classList = ref([]) +/** 奖项列表(来自接口 /stuwork/rewardrule/list,用于班级的奖项类型可传 ruleType 筛选) */ +const rewardRuleList = ref([]) // 提交表单数据 const form = reactive({ @@ -91,8 +102,8 @@ const dataRules = { classCode: [ { required: true, message: '请选择班号', trigger: 'change' } ], - ruleName: [ - { required: true, message: '请输入奖项名称', trigger: 'blur' } + ruleId: [ + { required: true, message: '请选择奖项名称', trigger: 'change' } ] } @@ -117,6 +128,8 @@ const openDialog = async (type: string = 'add', row?: any) => { form.ruleId = row.ruleId || '' form.ruleName = row.ruleName || '' form.remarks = row.remarks || '' + // 选择奖项后同步 ruleName + handleRewardRuleChange(form.ruleId) // 如果需要获取详情 if (row.id && (!row.ruleName || !row.remarks)) { @@ -138,8 +151,12 @@ const openDialog = async (type: string = 'add', row?: any) => { } // 班级变化 -const handleClassChange = () => { - // 可以根据班级获取相关信息,这里暂时不实现 +const handleClassChange = () => {} + +// 选择奖项时同步 ruleName(提交时需要) +const handleRewardRuleChange = (id: string) => { + const item = rewardRuleList.value.find((r) => r.id === id) + form.ruleName = item ? item.ruleName : '' } // 提交表单 @@ -192,9 +209,21 @@ const getClassListData = async () => { } } +// 获取奖项列表(接口:GET /stuwork/rewardrule/list) +const getRewardRuleData = async () => { + try { + const res = await getRewardRuleList() + const list = res.data && Array.isArray(res.data) ? res.data : [] + rewardRuleList.value = list + } catch (err) { + rewardRuleList.value = [] + } +} + // 初始化 onMounted(() => { getClassListData() + getRewardRuleData() }) // 暴露方法 diff --git a/src/views/stuwork/rewarddorm/form.vue b/src/views/stuwork/rewarddorm/form.vue index 9cc9dab..de9a9e8 100644 --- a/src/views/stuwork/rewarddorm/form.vue +++ b/src/views/stuwork/rewarddorm/form.vue @@ -12,6 +12,39 @@ label-width="100px" v-loading="loading"> + + + + + + + + + + + + + + + + - - + + filterable + style="width: 100%" + @change="handleRewardRuleChange"> + + @@ -66,6 +107,9 @@ import { ref, reactive, nextTick, onMounted } from 'vue' import { useMessage } from '/@/hooks/message' import { addObj, editObj, getDetail } from '/@/api/stuwork/rewarddorm' import { dormRoomList } from '/@/api/stuwork/dormroom' +import { getList as getRewardRuleList } from '/@/api/stuwork/rewardrule' +import { queryAllSchoolYear } from '/@/api/basic/basicyear' +import { getDicts } from '/@/api/admin/dict' const emit = defineEmits(['refresh']) @@ -75,10 +119,16 @@ const visible = ref(false) const loading = ref(false) const operType = ref('add') const roomList = ref([]) +const schoolYearList = ref([]) +const schoolTermList = ref([]) +/** 奖项列表(来自接口 /stuwork/rewardrule/list) */ +const rewardRuleList = ref([]) -// 提交表单数据 +// 提交表单数据(与接口文档一致:roomNo, ruleId, ruleName, schoolYear, schoolTerm, remarks) const form = reactive({ id: '', + schoolYear: '', + schoolTerm: '', roomNo: '', ruleId: '', ruleName: '', @@ -87,11 +137,17 @@ const form = reactive({ // 定义校验规则 const dataRules = { + schoolYear: [ + { required: true, message: '请选择学年', trigger: 'change' } + ], + schoolTerm: [ + { required: true, message: '请选择学期', trigger: 'change' } + ], roomNo: [ { required: true, message: '请选择宿舍号', trigger: 'change' } ], - ruleName: [ - { required: true, message: '请输入奖项名称', trigger: 'blur' } + ruleId: [ + { required: true, message: '请选择奖项名称', trigger: 'change' } ] } @@ -104,6 +160,8 @@ const openDialog = async (type: string = 'add', row?: any) => { nextTick(() => { dataFormRef.value?.resetFields() form.id = '' + form.schoolYear = '' + form.schoolTerm = '' form.roomNo = '' form.ruleId = '' form.ruleName = '' @@ -112,23 +170,27 @@ const openDialog = async (type: string = 'add', row?: any) => { // 编辑时填充数据 if (type === 'edit' && row) { form.id = row.id + form.schoolYear = row.schoolYear || '' + form.schoolTerm = row.schoolTerm || '' form.roomNo = row.roomNo || '' form.ruleId = row.ruleId || '' form.ruleName = row.ruleName || '' form.remarks = row.remarks || '' + handleRewardRuleChange(form.ruleId) // 如果需要获取详情 - if (row.id && (!row.ruleName || !row.remarks)) { + if (row.id && (!row.ruleName || !row.schoolYear)) { loading.value = true getDetail(row.id).then((res: any) => { if (res.data) { + form.schoolYear = res.data.schoolYear || '' + form.schoolTerm = res.data.schoolTerm || '' form.roomNo = res.data.roomNo || '' form.ruleId = res.data.ruleId || '' form.ruleName = res.data.ruleName || '' form.remarks = res.data.remarks || '' } - }).catch((err) => { - }).finally(() => { + }).catch(() => {}).finally(() => { loading.value = false }) } @@ -136,6 +198,12 @@ const openDialog = async (type: string = 'add', row?: any) => { }) } +// 选择奖项时同步 ruleName(提交时需要) +const handleRewardRuleChange = (id: string) => { + const item = rewardRuleList.value.find((r) => r.id === id) + form.ruleName = item ? item.ruleName : '' +} + // 提交表单 const onSubmit = async () => { if (!dataFormRef.value) return @@ -145,10 +213,13 @@ const onSubmit = async () => { loading.value = true try { + // 与接口文档一致:roomNo, ruleId, ruleName, schoolYear, schoolTerm, remarks const submitData = { roomNo: form.roomNo, - ruleId: form.ruleId || '', // 如果没有ruleId,传空字符串 + ruleId: form.ruleId != null && form.ruleId !== '' ? String(form.ruleId) : '', ruleName: form.ruleName, + schoolYear: form.schoolYear, + schoolTerm: form.schoolTerm, remarks: form.remarks || '' } @@ -164,8 +235,8 @@ const onSubmit = async () => { } visible.value = false emit('refresh') - } catch (err: any) { - useMessage().error(err.msg || (operType.value === 'add' ? '新增失败' : '编辑失败')) + } catch (_err) { + // 不再在此处弹 error:request 拦截器已统一弹过,避免重复两个 error 弹窗 } finally { loading.value = false } @@ -186,9 +257,50 @@ const getRoomListData = async () => { } } +// 获取奖项列表(接口:GET /stuwork/rewardrule/list) +const getRewardRuleData = async () => { + try { + const res = await getRewardRuleList() + const list = res.data && Array.isArray(res.data) ? res.data : [] + rewardRuleList.value = list + } catch (err) { + rewardRuleList.value = [] + } +} + +// 获取学年列表 +const getSchoolYearData = async () => { + try { + const res = await queryAllSchoolYear() + schoolYearList.value = res.data && Array.isArray(res.data) ? res.data : [] + } catch (err) { + schoolYearList.value = [] + } +} + +// 获取学期字典 +const getSchoolTermData = async () => { + try { + const res = await getDicts('school_term') + if (res.data && Array.isArray(res.data)) { + schoolTermList.value = res.data.map((item: any) => ({ + label: item.label || item.dictLabel || item.name, + value: item.value ?? item.dictValue ?? item.code + })) + } else { + schoolTermList.value = [] + } + } catch (err) { + schoolTermList.value = [] + } +} + // 初始化 onMounted(() => { getRoomListData() + getRewardRuleData() + getSchoolYearData() + getSchoolTermData() }) // 暴露方法 diff --git a/src/views/stuwork/stuconduct/indexTerm.vue b/src/views/stuwork/stuconduct/indexTerm.vue index 6db32ef..f06e93f 100644 --- a/src/views/stuwork/stuconduct/indexTerm.vue +++ b/src/views/stuwork/stuconduct/indexTerm.vue @@ -104,12 +104,62 @@ + + + +
+ + {{ viewRow.stuNo }} + {{ viewRow.realName }} + {{ queryForm.schoolYear }} + {{ formatSchoolTerm(queryForm.schoolTerm) }} + + {{ viewRow.score != null && viewRow.score !== undefined ? Number(viewRow.score).toFixed(2) : '-' }} + + +
+
考核记录
+ + + + + + + + + + + + + + +
+ + diff --git a/src/views/stuwork/stuleaveapply/form.vue b/src/views/stuwork/stuleaveapply/form.vue index b892f8d..294601f 100644 --- a/src/views/stuwork/stuleaveapply/form.vue +++ b/src/views/stuwork/stuleaveapply/form.vue @@ -188,9 +188,13 @@ const handleClassChange = async (classCode: string) => { } try { - const res = await queryStudentListByClass({ classCode, current: 1, size: 10000 }) - if (res.data && Array.isArray(res.data.records)) { - studentList.value = res.data.records + // 接口文档:GET 仅 classCode,返回 data 为数组 + const res = await queryStudentListByClass({ classCode }) + const data = res?.data + if (Array.isArray(data)) { + studentList.value = data + } else if (data?.records && Array.isArray(data.records)) { + studentList.value = data.records } else { studentList.value = [] } diff --git a/src/views/stuwork/stupunlish/form.vue b/src/views/stuwork/stupunlish/form.vue index 1f75f72..98ce571 100644 --- a/src/views/stuwork/stupunlish/form.vue +++ b/src/views/stuwork/stupunlish/form.vue @@ -181,9 +181,13 @@ const handleClassChange = async (classCode: string) => { } try { - const res = await queryStudentListByClass({ classCode, current: 1, size: 10000 }) - if (res.data && Array.isArray(res.data.records)) { - studentList.value = res.data.records + // 接口文档:GET,仅 classCode;返回 data 为数组,非 data.records + const res = await queryStudentListByClass({ classCode }) + const data = res?.data + if (Array.isArray(data)) { + studentList.value = data + } else if (data?.records && Array.isArray(data.records)) { + studentList.value = data.records } else { studentList.value = [] } diff --git a/src/views/stuwork/stutemleaveapply/form.vue b/src/views/stuwork/stutemleaveapply/form.vue index 5d38a5b..fe8dd25 100644 --- a/src/views/stuwork/stutemleaveapply/form.vue +++ b/src/views/stuwork/stutemleaveapply/form.vue @@ -305,13 +305,18 @@ const getClassListData = async () => { } } -// 获取学生列表 +// 获取学生列表(接口文档:GET 仅 classCode,返回 data 为数组) const getStudentListData = async () => { if (!form.classCode) return try { - const res = await queryStudentListByClass(form.classCode) - if (res.data) { - studentList.value = Array.isArray(res.data) ? res.data : [] + const res = await queryStudentListByClass({ classCode: form.classCode }) + const data = res?.data + if (Array.isArray(data)) { + studentList.value = data + } else if (data?.records && Array.isArray(data.records)) { + studentList.value = data.records + } else { + studentList.value = [] } } catch (err) { studentList.value = [] diff --git a/src/views/stuwork/stuturnover/index.vue b/src/views/stuwork/stuturnover/index.vue index 1404761..727500d 100644 --- a/src/views/stuwork/stuturnover/index.vue +++ b/src/views/stuwork/stuturnover/index.vue @@ -207,7 +207,7 @@
- +