Merge remote-tracking branch 'origin/developer' into developer
This commit is contained in:
29
src/App.vue
29
src/App.vue
@@ -82,6 +82,19 @@ async function validateCachedRoleId(): Promise<boolean> {
|
||||
}
|
||||
}
|
||||
|
||||
/** 有 token 时执行角色校验:缓存 roleId 无效则清缓存并弹框,缺角色信息则弹框(与 onMounted 内逻辑一致) */
|
||||
async function runRoleValidationAndOpenDialogIfNeeded() {
|
||||
if (!Session.getToken()) return;
|
||||
const needOpenByInvalidRole = await validateCachedRoleId();
|
||||
if (needOpenByInvalidRole && !isRoleDialogTriggered()) {
|
||||
setRoleDialogTriggered(true);
|
||||
mittBus.emit('openRoleSelectDialog');
|
||||
} else if (!needOpenByInvalidRole && needRoleSelection() && !isRoleDialogTriggered()) {
|
||||
setRoleDialogTriggered(true);
|
||||
mittBus.emit('openRoleSelectDialog');
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 唯一入口:只通过事件打开,且只打开一次;延迟打开以等待异步组件挂载
|
||||
mittBus.on('openRoleSelectDialog', () => {
|
||||
@@ -99,6 +112,10 @@ onMounted(() => {
|
||||
};
|
||||
tryOpen();
|
||||
});
|
||||
// token 来自 URL 时由路由 afterEach 发出,此时 App 已挂载但 onMounted 时可能尚无 token,需在此补跑一次校验
|
||||
mittBus.on('validateRoleFromUrl', () => {
|
||||
runRoleValidationAndOpenDialogIfNeeded();
|
||||
});
|
||||
nextTick(async () => {
|
||||
// 监听布局配置弹窗点击打开
|
||||
mittBus.on('openSettingsDrawer', () => {
|
||||
@@ -114,22 +131,14 @@ onMounted(() => {
|
||||
stores.setCurrenFullscreen(Session.get('isTagsViewCurrenFull'));
|
||||
}
|
||||
// 有 token 时:先校验缓存 roleId 是否仍有效,无效则清缓存并弹框选角色
|
||||
if (Session.getToken()) {
|
||||
const needOpenByInvalidRole = await validateCachedRoleId();
|
||||
if (needOpenByInvalidRole && !isRoleDialogTriggered()) {
|
||||
setRoleDialogTriggered(true);
|
||||
mittBus.emit('openRoleSelectDialog');
|
||||
} else if (!needOpenByInvalidRole && needRoleSelection() && !isRoleDialogTriggered()) {
|
||||
setRoleDialogTriggered(true);
|
||||
mittBus.emit('openRoleSelectDialog');
|
||||
}
|
||||
}
|
||||
await runRoleValidationAndOpenDialogIfNeeded();
|
||||
});
|
||||
});
|
||||
// 页面销毁时,关闭监听
|
||||
onUnmounted(() => {
|
||||
mittBus.off('openSettingsDrawer', () => {});
|
||||
mittBus.off('openRoleSelectDialog');
|
||||
mittBus.off('validateRoleFromUrl');
|
||||
});
|
||||
// 监听路由的变化,设置网站标题
|
||||
watch(
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useKeepALiveNames } from '/@/stores/keepAliveNames';
|
||||
import { useRoutesList } from '/@/stores/routesList';
|
||||
import { useUserInfo } from '/@/stores/userInfo';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import mittBus from '/@/utils/mitt';
|
||||
import { staticRoutes, notFoundAndNoPower } from '/@/router/route';
|
||||
import { initBackEndControlRoutes } from '/@/router/backEnd';
|
||||
import { flowConfig } from '/@/flow/designer/config/flow-config';
|
||||
@@ -98,6 +99,8 @@ router.beforeEach(async (to, from, next) => {
|
||||
const urlToken = to.query?.token as string | undefined;
|
||||
if (urlToken) {
|
||||
useUserInfo().setTokenCache(urlToken, to.query?.refresh_token as string | undefined);
|
||||
// 标记「本次 token 来自 URL」,供 afterEach 触发角色校验;因 setTokenCache 在 beforeEach 执行,可能晚于 App.onMounted,需单独触发校验以清除无效 roleId
|
||||
Session.set('tokenFromUrl', 1);
|
||||
}
|
||||
// 若上面刚写了 token,后续用去掉 token 的 query 做一次 replace(在 init 之后统一做,保证只一次导航、tagsView 能正确加 tag)
|
||||
const stripTokenQuery =
|
||||
@@ -148,6 +151,11 @@ router.beforeEach(async (to, from, next) => {
|
||||
router.afterEach(() => {
|
||||
NProgress.done();
|
||||
NextLoading.done();
|
||||
// token 来自 URL 时,App.onMounted 可能已先执行且当时无 token,需在导航完成后触发一次角色校验(清无效 roleId + 弹框)
|
||||
if (Session.get('tokenFromUrl')) {
|
||||
Session.remove('tokenFromUrl');
|
||||
mittBus.emit('validateRoleFromUrl');
|
||||
}
|
||||
});
|
||||
|
||||
// 导出路由
|
||||
|
||||
1
src/types/mitt.d.ts
vendored
1
src/types/mitt.d.ts
vendored
@@ -24,6 +24,7 @@ declare type MittType<T = any> = {
|
||||
onTagsViewRefreshRouterView?: T;
|
||||
onCurrentContextmenuClick?: T;
|
||||
openRoleSelectDialog?: string;
|
||||
validateRoleFromUrl?: string;
|
||||
};
|
||||
|
||||
// mitt 参数类型定义
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
<div class="header-actions">
|
||||
<el-button icon="Plus" type="primary" @click="formDialogRef.openDialog()"> 新增 </el-button>
|
||||
<el-button icon="Upload" type="success" class="ml10" @click="handleImport"> 导入 </el-button>
|
||||
<el-button icon="Download" type="warning" class="ml10" @click="handleExport"> 导出 </el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList">
|
||||
<TableColumnControl
|
||||
ref="columnControlRef"
|
||||
@@ -108,47 +107,35 @@
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 导入弹窗 -->
|
||||
<el-dialog title="导入获奖活动信息" v-model="importDialogVisible" :width="500" :close-on-click-modal="false" draggable>
|
||||
<div style="margin-bottom: 15px">
|
||||
<el-button icon="Download" type="success" @click="handleDownloadTemplate"> 下载模板 </el-button>
|
||||
</div>
|
||||
<el-upload ref="uploadRef" :auto-upload="false" :on-change="handleFileChange" :limit="1" accept=".xlsx,.xls" drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">只能上传 xlsx/xls 文件</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="importDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :disabled="!importFile || importLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<upload-excel
|
||||
ref="uploadExcelRef"
|
||||
:title="'导入活动获奖'"
|
||||
:url="'/stuwork/file/importActivityAwards'"
|
||||
:temp-url="'/stuwork/file/exportActivityAwardsTemplate'"
|
||||
@refreshDataList="getDataList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ActivityAwards">
|
||||
import { reactive, ref } from 'vue';
|
||||
import { reactive, ref, defineAsyncComponent } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, delObj } from '/@/api/stuwork/activityawards';
|
||||
import { exportActivityAwardsTemplate, importActivityAwards, downloadBlobFile } from '/@/api/stuwork/file';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import { parseTime } from '/@/utils/formatTime';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import { UploadFilled, List, Trophy, CreditCard, Avatar, Medal, Calendar, EditPen, Setting, Menu, Document } from '@element-plus/icons-vue';
|
||||
import { List, Trophy, CreditCard, Avatar, Medal, Calendar, EditPen, Setting, Menu, Document } from '@element-plus/icons-vue';
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
import FormDialog from './form.vue';
|
||||
|
||||
// 引入组件
|
||||
const UploadExcel = defineAsyncComponent(() => import('/@/components/Upload/Excel.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref();
|
||||
const uploadRef = ref();
|
||||
const uploadExcelRef = ref();
|
||||
const columnControlRef = ref();
|
||||
const showSearch = ref(false);
|
||||
const importDialogVisible = ref(false);
|
||||
const importFile = ref<File | null>(null);
|
||||
const importLoading = ref(false);
|
||||
|
||||
// 表格列配置
|
||||
const tableColumns = [
|
||||
@@ -205,47 +192,8 @@ const handleDelete = async (row: any) => {
|
||||
|
||||
// 导入
|
||||
const handleImport = () => {
|
||||
importDialogVisible.value = true;
|
||||
importFile.value = null;
|
||||
uploadRef.value?.clearFiles();
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
await downloadBlobFile(exportActivityAwardsTemplate(), '活动获奖导入模板.xlsx');
|
||||
};
|
||||
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
await downloadBlobFile(exportActivityAwardsTemplate(), '活动获奖导入模板.xlsx');
|
||||
};
|
||||
|
||||
// 文件变化
|
||||
const handleFileChange = (file: any) => {
|
||||
importFile.value = file.raw;
|
||||
};
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (!importFile.value) {
|
||||
useMessage().warning('请选择要导入的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
importLoading.value = true;
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('file', importFile.value);
|
||||
await importActivityAwards(formData);
|
||||
useMessage().success('导入成功');
|
||||
importDialogVisible.value = false;
|
||||
importFile.value = null;
|
||||
uploadRef.value?.clearFiles();
|
||||
getDataList();
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败');
|
||||
} finally {
|
||||
importLoading.value = false;
|
||||
if (uploadExcelRef.value) {
|
||||
uploadExcelRef.value.show();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -129,28 +129,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ActivityInfoSubSignup">
|
||||
import { reactive, ref, onMounted, computed } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, delObj, exportExcel, getActivityInfoList, getActivityInfoSubList } from '/@/api/stuwork/activityinfosubsignup';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import {
|
||||
List,
|
||||
Trophy,
|
||||
Document,
|
||||
Files,
|
||||
CreditCard,
|
||||
Avatar,
|
||||
OfficeBuilding,
|
||||
Grid,
|
||||
UserFilled,
|
||||
Phone,
|
||||
Setting,
|
||||
Menu,
|
||||
Search,
|
||||
Document as DocIcon,
|
||||
} from '@element-plus/icons-vue';
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
import { reactive, ref, onMounted, computed } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, getActivityInfoList, getActivityInfoSubList } from "/@/api/stuwork/activityinfosubsignup";
|
||||
import { makeExportActivitySignUpDetailTask } from "/@/api/stuwork/file";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
import { List, Trophy, Document, Files, CreditCard, Avatar, OfficeBuilding, Grid, UserFilled, Phone, Setting, Menu, Search, Document as DocIcon } from '@element-plus/icons-vue'
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn'
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref();
|
||||
@@ -244,27 +230,16 @@ const handleDelete = async (row: any) => {
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
exportLoading.value = true;
|
||||
exportLoading.value = true
|
||||
try {
|
||||
const res = await exportExcel(state.queryForm);
|
||||
const blob = new Blob([res.data as BlobPart], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
});
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = `活动报名表_${new Date().getTime()}.xlsx`;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(link);
|
||||
useMessage().success('导出成功');
|
||||
await makeExportActivitySignUpDetailTask(state.queryForm)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败');
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
} finally {
|
||||
exportLoading.value = false;
|
||||
exportLoading.value = false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 获取活动主题列表
|
||||
const getActivityInfoListData = async () => {
|
||||
|
||||
@@ -269,34 +269,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassFeeLog">
|
||||
import { reactive, ref, onMounted, computed } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, delObj, exportExcel, getSummary } from '/@/api/stuwork/classfeelog';
|
||||
import { getDeptList } from '/@/api/basic/basicclass';
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear';
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import FormDialog from './form.vue';
|
||||
import {
|
||||
List,
|
||||
Calendar,
|
||||
Clock,
|
||||
OfficeBuilding,
|
||||
Grid,
|
||||
Collection,
|
||||
Money,
|
||||
User,
|
||||
Document,
|
||||
Setting,
|
||||
Menu,
|
||||
Search,
|
||||
FolderAdd,
|
||||
EditPen,
|
||||
DataAnalysis,
|
||||
} from '@element-plus/icons-vue';
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
import { reactive, ref, onMounted, computed } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, getSummary } from "/@/api/stuwork/classfeelog";
|
||||
import { makeExportClassFundTask } from "/@/api/stuwork/file";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
import FormDialog from './form.vue'
|
||||
import { List, Calendar, Clock, OfficeBuilding, Grid, Collection, Money, User, Document, Setting, Menu, Search, FolderAdd, EditPen, DataAnalysis } from '@element-plus/icons-vue'
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref();
|
||||
@@ -402,24 +387,12 @@ const handleViewAttachment = (row: any) => {
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const res = await exportExcel(state.queryForm);
|
||||
const blob = new Blob([res], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
});
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
const fileName = `班费记录_${new Date().getTime()}.xlsx`;
|
||||
link.setAttribute('download', fileName);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
useMessage().success('导出成功');
|
||||
await makeExportClassFundTask(state.queryForm)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败');
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<el-button icon="Download" type="success" @click="handleExport"> 导出 </el-button>
|
||||
<el-button icon="Download" type="primary" plain @click="handleAsyncExport"> 异步导出 </el-button>
|
||||
<el-button icon="Refresh" type="primary" class="ml10" @click="handleSync"> 同步教室安排 </el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList">
|
||||
<TableColumnControl
|
||||
@@ -175,6 +176,7 @@
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, exportData, syncClassroomArrangement } from '/@/api/stuwork/classroombase';
|
||||
import { makeExportClassAssetsTask } from '/@/api/stuwork/file';
|
||||
import { getDeptListByLevelTwo } from '/@/api/basic/basicdept';
|
||||
import { queryAllClass } from '/@/api/basic/basicclass';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
@@ -360,6 +362,16 @@ const handleExport = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 异步导出
|
||||
const handleAsyncExport = async () => {
|
||||
try {
|
||||
await makeExportClassAssetsTask(searchForm);
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载');
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 同步教室安排
|
||||
const handleSync = async () => {
|
||||
const { confirm } = useMessageBox();
|
||||
|
||||
@@ -224,32 +224,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ClassSafeEdu">
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, delObj, exportExcel, statisticsByYearTerm } from '/@/api/stuwork/classsafeedu';
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass';
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import FormDialog from './form.vue';
|
||||
import DetailDialog from './detail.vue';
|
||||
import {
|
||||
List,
|
||||
Calendar,
|
||||
Clock,
|
||||
Grid,
|
||||
Trophy,
|
||||
User,
|
||||
Location,
|
||||
UserFilled,
|
||||
Setting,
|
||||
Menu,
|
||||
Search,
|
||||
Document,
|
||||
DataAnalysis,
|
||||
} from '@element-plus/icons-vue';
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
import { reactive, ref, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, statisticsByYearTerm } from "/@/api/stuwork/classsafeedu";
|
||||
import { makeExportSafetyEducationTask } from "/@/api/stuwork/file";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
import FormDialog from './form.vue'
|
||||
import DetailDialog from './detail.vue'
|
||||
import { List, Calendar, Clock, Grid, Trophy, User, Location, UserFilled, Setting, Menu, Search, Document, DataAnalysis } from '@element-plus/icons-vue'
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn'
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref();
|
||||
@@ -346,35 +333,12 @@ const handleViewImage = (url: string) => {
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const res = await exportExcel(state.queryForm);
|
||||
|
||||
// 创建blob对象
|
||||
const blob = new Blob([res], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
});
|
||||
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
|
||||
// 设置文件名
|
||||
const fileName = `安全教育_${new Date().getTime()}.xlsx`;
|
||||
link.setAttribute('download', fileName);
|
||||
|
||||
// 触发下载
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
|
||||
// 清理
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
|
||||
useMessage().success('导出成功');
|
||||
await makeExportSafetyEducationTask(state.queryForm)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败');
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
const handleView = (row: any) => {
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<el-button icon="Upload" type="primary" @click="handleImport"> 导入 </el-button>
|
||||
<el-button icon="Download" type="warning" class="ml10" @click="handleExport"> 导出 </el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -162,43 +161,61 @@
|
||||
</el-dialog>
|
||||
|
||||
<!-- 导入对话框 -->
|
||||
<upload-excel
|
||||
ref="uploadExcelRef"
|
||||
:title="'导入宿舍月卫生'"
|
||||
:url="'/stuwork/file/importDormHygieneMonthly'"
|
||||
:temp-url="templateUrl"
|
||||
@refreshDataList="getDataList"
|
||||
/>
|
||||
<el-dialog v-model="importDialogVisible" title="导入宿舍月卫生" width="500px" :close-on-click-modal="false">
|
||||
<el-form :model="importForm" ref="importFormRef" label-width="80px" style="margin-bottom: 15px">
|
||||
<el-form-item label="楼号" prop="buildingNo">
|
||||
<el-select v-model="importForm.buildingNo" placeholder="请选择楼号" filterable style="width: 100%">
|
||||
<el-option v-for="item in buildingList" :key="item.buildingNo" :label="item.buildingNo" :value="item.buildingNo" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="月份" prop="month">
|
||||
<el-date-picker v-model="importForm.month" type="month" placeholder="选择月份" format="YYYY-MM" value-format="YYYY-MM" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="Download" type="success" @click="handleDownloadTemplate"> 下载模板 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-upload ref="importUploadRef" :auto-upload="false" :on-change="handleImportFileChange" :limit="1" accept=".xlsx,.xls" drag>
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip text-center">只能上传 xlsx/xls 文件,请先选择楼号和月份后下载模板</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<el-button @click="importDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :disabled="!importFile || importLoading">确认导入</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="DormHygieneMonthly">
|
||||
import { reactive, ref, onMounted, defineAsyncComponent } from 'vue';
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { fetchList, addObj, editObj, delObj, triggerEvaluation } from '/@/api/stuwork/dormhygienemonthly';
|
||||
import { exportDormHygieneMonthlyTemplate, downloadBlobFile } from '/@/api/stuwork/file';
|
||||
import { exportDormHygieneMonthlyTemplate, importDormHygieneMonthly, downloadBlobFile } from '/@/api/stuwork/file';
|
||||
import { getBuildingList } from '/@/api/stuwork/dormbuilding';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { Search, Document, Plus, Edit, Delete, Promotion } from '@element-plus/icons-vue';
|
||||
|
||||
// 引入组件
|
||||
const UploadExcel = defineAsyncComponent(() => import('/@/components/Upload/Excel.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref();
|
||||
const formRef = ref();
|
||||
const evalFormRef = ref();
|
||||
const uploadExcelRef = ref();
|
||||
const importFormRef = ref();
|
||||
const importUploadRef = ref();
|
||||
const showSearch = ref(true);
|
||||
const loading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
const evalLoading = ref(false);
|
||||
const importLoading = ref(false);
|
||||
const dataList = ref<any[]>([]);
|
||||
const buildingList = ref<any[]>([]);
|
||||
const dialogVisible = ref(false);
|
||||
const evalDialogVisible = ref(false);
|
||||
const dialogTitle = ref('新增宿舍月卫生');
|
||||
// 模板文件URL
|
||||
const templateUrl = ref('/stuwork/file/exportDormHygieneMonthlyTemplate');
|
||||
const evalDialogVisible = ref(false);
|
||||
const importDialogVisible = ref(false);
|
||||
const importFile = ref<File | null>(null);
|
||||
|
||||
// 分页
|
||||
const page = reactive({
|
||||
@@ -229,6 +246,12 @@ const evalForm = reactive({
|
||||
month: '',
|
||||
});
|
||||
|
||||
// 导入表单
|
||||
const importForm = reactive({
|
||||
buildingNo: '',
|
||||
month: '',
|
||||
});
|
||||
|
||||
// 表单校验规则
|
||||
const rules = {
|
||||
month: [{ required: true, message: '请选择月份', trigger: 'change' }],
|
||||
@@ -344,14 +367,55 @@ const handleEvaluation = () => {
|
||||
|
||||
// 导入
|
||||
const handleImport = () => {
|
||||
if (uploadExcelRef.value) {
|
||||
uploadExcelRef.value.show();
|
||||
importForm.buildingNo = '';
|
||||
importForm.month = '';
|
||||
importFile.value = null;
|
||||
importDialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
if (!importForm.buildingNo) {
|
||||
useMessage().warning('请先选择楼号');
|
||||
return;
|
||||
}
|
||||
if (!importForm.month) {
|
||||
useMessage().warning('请先选择月份');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await downloadBlobFile(exportDormHygieneMonthlyTemplate(importForm), `宿舍月卫生导入模板_${importForm.month}.xlsx`);
|
||||
} catch (err: any) {
|
||||
useMessage().error(err?.msg || '下载模板失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
await downloadBlobFile(exportDormHygieneMonthlyTemplate(searchForm), '宿舍月卫生.xlsx');
|
||||
// 导入文件变化
|
||||
const handleImportFileChange = (file: any) => {
|
||||
importFile.value = file.raw;
|
||||
};
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (!importFile.value) {
|
||||
useMessage().warning('请先选择要上传的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
importLoading.value = true;
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('file', importFile.value);
|
||||
await importDormHygieneMonthly(formData);
|
||||
useMessage().success('导入成功');
|
||||
importDialogVisible.value = false;
|
||||
importFile.value = null;
|
||||
getDataList();
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败');
|
||||
} finally {
|
||||
importLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 提交评比
|
||||
|
||||
@@ -183,16 +183,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="DormHygieneMonthly">
|
||||
import { ref, reactive, defineAsyncComponent, computed, onMounted, nextTick } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, putObj, delObjs } from '/@/api/stuwork/dormreform';
|
||||
import { getBuildingList } from '/@/api/stuwork/dormbuilding';
|
||||
import { getDormRoomDataByBuildingNo } from '/@/api/stuwork/dormroom';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { downBlobFile, adaptationUrl } from '/@/utils/other';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import { ref, reactive, defineAsyncComponent, computed, onMounted, nextTick } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, putObj, delObjs } from "/@/api/stuwork/dormreform";
|
||||
import { makeExportDormReformTask } from "/@/api/stuwork/file";
|
||||
import { getBuildingList } from "/@/api/stuwork/dormbuilding";
|
||||
import { getDormRoomDataByBuildingNo } from "/@/api/stuwork/dormroom";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
|
||||
// 引入组件
|
||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||
@@ -345,9 +345,14 @@ const handleDelete = async (row: any) => {
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleExport = () => {
|
||||
downBlobFile(adaptationUrl('/stuwork/dormreform/export'), searchForm, '月卫生检查整改.xlsx');
|
||||
};
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
await makeExportDormReformTask(searchForm)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化整改结果
|
||||
const formatReformStatus = (value: string | number) => {
|
||||
|
||||
@@ -163,16 +163,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="DormRoom">
|
||||
import { ref, reactive, defineAsyncComponent, onMounted, computed, nextTick } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
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';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import { ref, reactive, defineAsyncComponent, onMounted, computed, nextTick } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, editDept } from "/@/api/stuwork/dormroom";
|
||||
import { makeExportDormRoomTask } from "/@/api/stuwork/file";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { getBuildingList } from "/@/api/stuwork/dormbuilding";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
|
||||
// 引入组件
|
||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||
@@ -321,12 +321,12 @@ const confirmDeptAssign = async () => {
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
await downBlobFile(adaptationUrl('/stuwork/dormroom/export'), searchForm, '宿舍房间.xlsx');
|
||||
useMessage().success('导出成功');
|
||||
await makeExportDormRoomTask(searchForm)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败');
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 获取学院列表
|
||||
const getDeptListData = async () => {
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<!-- 顶部工具栏 -->
|
||||
<div class="mb10">
|
||||
<el-button
|
||||
icon="Download"
|
||||
type="primary"
|
||||
plain
|
||||
@click="handleExport">
|
||||
导出
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
: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" />
|
||||
@@ -20,7 +29,13 @@
|
||||
<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>
|
||||
<el-button
|
||||
icon="View"
|
||||
text
|
||||
type="primary"
|
||||
@click="handleView(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -29,10 +44,11 @@
|
||||
</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';
|
||||
import { reactive, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { queryStudentAbnormal } from "/@/api/stuwork/dormroomstudent";
|
||||
import { makeExportDormStudentAbnormalTask } from "/@/api/stuwork/file";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
@@ -75,6 +91,16 @@ const handleView = (row: any) => {
|
||||
// TODO: 实现查看详情功能
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
await makeExportDormStudentAbnormalTask()
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err?.msg || '导出失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getDataList();
|
||||
|
||||
@@ -191,15 +191,20 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="DormRoomStudent">
|
||||
import { reactive, ref, onMounted, computed, nextTick } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
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';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
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 {
|
||||
makeExportDormStudentTask,
|
||||
makeExportDormStudentAbnormalTask,
|
||||
makeExportDormStatisticsTask
|
||||
} from "/@/api/stuwork/file";
|
||||
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 TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
import FormDialog from './form.vue';
|
||||
import TransferDialog from './transfer.vue';
|
||||
import SwapDialog from './swap.vue';
|
||||
@@ -374,26 +379,16 @@ const handleExport = async () => {
|
||||
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 || '导出失败');
|
||||
realName: searchForm.realName
|
||||
}
|
||||
};
|
||||
await makeExportDormStatisticsTask(params)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err?.msg || '导出失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 名单导出:与导出共用空 n 人宿舍导出接口,文件名区分
|
||||
// 名单导出:住宿学生名单导出
|
||||
const handleExportList = async () => {
|
||||
try {
|
||||
const params = {
|
||||
@@ -404,24 +399,14 @@ const handleExportList = async () => {
|
||||
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 || '导出失败');
|
||||
realName: searchForm.realName
|
||||
}
|
||||
};
|
||||
await makeExportDormStudentTask(params)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err?.msg || '导出失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑(与转宿共用接口 edit,修改房间/床位/是否舍长)
|
||||
const handleEdit = (row: any) => {
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
<div class="header-actions">
|
||||
<el-button icon="Plus" type="primary" @click="formDialogRef.openDialog()"> 新增 </el-button>
|
||||
<el-button icon="Upload" type="success" class="ml10" @click="handleImport"> 导入 </el-button>
|
||||
<el-button icon="Download" type="warning" class="ml10" @click="handleExport"> 导出 </el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList">
|
||||
<TableColumnControl
|
||||
ref="columnControlRef"
|
||||
@@ -150,33 +149,21 @@
|
||||
<!-- 新增/编辑表单弹窗 -->
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 导入弹窗 -->
|
||||
<el-dialog title="导入文明班级" v-model="importDialogVisible" :width="500" :close-on-click-modal="false" draggable>
|
||||
<div style="margin-bottom: 15px">
|
||||
<el-button icon="Download" type="success" @click="handleDownloadTemplate"> 下载模板 </el-button>
|
||||
</div>
|
||||
<el-upload ref="uploadRef" :auto-upload="false" :on-change="handleFileChange" :limit="1" accept=".xlsx,.xls" drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">只能上传 xlsx/xls 文件</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="importDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :disabled="!importFile || importLoading">确 认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 导入对话框 -->
|
||||
<upload-excel
|
||||
ref="uploadExcelRef"
|
||||
:title="'导入文明班级'"
|
||||
:url="'/stuwork/file/importRewardClass'"
|
||||
:temp-url="'/stuwork/file/exportRewardClassTemplate'"
|
||||
@refreshDataList="getDataList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RewardClass">
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { reactive, ref, onMounted, defineAsyncComponent } from 'vue';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, delObj } from '/@/api/stuwork/rewardclass';
|
||||
import { exportRewardClassTemplate, importRewardClass, downloadBlobFile } from '/@/api/stuwork/file';
|
||||
import { getDeptList } from '/@/api/basic/basicclass';
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass';
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear';
|
||||
@@ -184,7 +171,6 @@ import { getDicts } from '/@/api/admin/dict';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import {
|
||||
UploadFilled,
|
||||
List,
|
||||
Calendar,
|
||||
Clock,
|
||||
@@ -201,9 +187,12 @@ import {
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
import FormDialog from './form.vue';
|
||||
|
||||
// 引入组件
|
||||
const UploadExcel = defineAsyncComponent(() => import('/@/components/Upload/Excel.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref();
|
||||
const uploadRef = ref();
|
||||
const uploadExcelRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const columnControlRef = ref();
|
||||
const showSearch = ref(true);
|
||||
@@ -211,9 +200,6 @@ const schoolYearList = ref<any[]>([]);
|
||||
const schoolTermList = ref<any[]>([]);
|
||||
const deptList = ref<any[]>([]);
|
||||
const classList = ref<any[]>([]);
|
||||
const importDialogVisible = ref(false);
|
||||
const importFile = ref<File | null>(null);
|
||||
const importLoading = ref(false);
|
||||
|
||||
// 表格列配置
|
||||
const tableColumns = [
|
||||
@@ -280,47 +266,8 @@ const handleReset = () => {
|
||||
|
||||
// 导入
|
||||
const handleImport = () => {
|
||||
importDialogVisible.value = true;
|
||||
importFile.value = null;
|
||||
uploadRef.value?.clearFiles();
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
await downloadBlobFile(exportRewardClassTemplate(), '文明班级导入模板.xlsx');
|
||||
};
|
||||
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
await downloadBlobFile(exportRewardClassTemplate(), '文明班级导入模板.xlsx');
|
||||
};
|
||||
|
||||
// 文件变化
|
||||
const handleFileChange = (file: any) => {
|
||||
importFile.value = file.raw;
|
||||
};
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (!importFile.value) {
|
||||
useMessage().warning('请选择要导入的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
importLoading.value = true;
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('file', importFile.value);
|
||||
await importRewardClass(formData);
|
||||
useMessage().success('导入成功');
|
||||
importDialogVisible.value = false;
|
||||
importFile.value = null;
|
||||
uploadRef.value?.clearFiles();
|
||||
getDataList();
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败');
|
||||
} finally {
|
||||
importLoading.value = false;
|
||||
if (uploadExcelRef.value) {
|
||||
uploadExcelRef.value.show();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
<div class="header-actions">
|
||||
<el-button icon="Plus" type="primary" @click="formDialogRef.openDialog()"> 新增 </el-button>
|
||||
<el-button icon="Upload" type="success" class="ml10" @click="handleImport"> 导入 </el-button>
|
||||
<el-button icon="Download" type="warning" class="ml10" @click="handleExport"> 导出 </el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList">
|
||||
<TableColumnControl
|
||||
ref="columnControlRef"
|
||||
@@ -137,53 +136,41 @@
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 导入对话框 -->
|
||||
<el-dialog title="导入数据" v-model="importDialogVisible" :width="500" :close-on-click-modal="false" draggable>
|
||||
<div style="margin-bottom: 15px">
|
||||
<el-button icon="Download" type="success" @click="handleDownloadTemplate"> 下载模板 </el-button>
|
||||
</div>
|
||||
<el-upload ref="uploadRef" :auto-upload="false" :on-change="handleFileChange" :limit="1" accept=".xlsx,.xls" drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">只能上传 xlsx/xls 文件</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="importDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleImportSubmit" :disabled="!importFile || importLoading">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<upload-excel
|
||||
ref="uploadExcelRef"
|
||||
:title="'导入文明宿舍'"
|
||||
:url="'/stuwork/file/importRewardDorm'"
|
||||
:temp-url="'/stuwork/file/exportRewardDormTemplate'"
|
||||
@refreshDataList="getDataList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RewardDorm">
|
||||
import { reactive, ref, onMounted, computed } from 'vue';
|
||||
import { reactive, ref, onMounted, computed, defineAsyncComponent } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, delObj } from '/@/api/stuwork/rewarddorm';
|
||||
import { exportRewardDormTemplate, importRewardDorm, downloadBlobFile } from '/@/api/stuwork/file';
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import { UploadFilled, List, Calendar, Clock, House, Trophy, EditPen, Setting, Menu, Search, Document } from '@element-plus/icons-vue';
|
||||
import { List, Calendar, Clock, House, Trophy, EditPen, Setting, Menu, Search, Document } from '@element-plus/icons-vue';
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
import FormDialog from './form.vue';
|
||||
|
||||
// 引入组件
|
||||
const UploadExcel = defineAsyncComponent(() => import('/@/components/Upload/Excel.vue'));
|
||||
|
||||
// 定义变量
|
||||
const route = useRoute();
|
||||
const formDialogRef = ref();
|
||||
const uploadRef = ref();
|
||||
const uploadExcelRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const columnControlRef = ref();
|
||||
const showSearch = ref(true);
|
||||
const schoolYearList = ref<any[]>([]);
|
||||
const schoolTermList = ref<any[]>([]);
|
||||
const importDialogVisible = ref(false);
|
||||
const importFile = ref<File | null>(null);
|
||||
const importLoading = ref(false);
|
||||
|
||||
// 表格列配置
|
||||
const tableColumns = [
|
||||
@@ -243,47 +230,8 @@ const handleReset = () => {
|
||||
|
||||
// 导入
|
||||
const handleImport = () => {
|
||||
importDialogVisible.value = true;
|
||||
importFile.value = null;
|
||||
uploadRef.value?.clearFiles();
|
||||
};
|
||||
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
await downloadBlobFile(exportRewardDormTemplate(), '文明宿舍导入模板.xlsx');
|
||||
};
|
||||
|
||||
// 下载模板
|
||||
const handleDownloadTemplate = async () => {
|
||||
await downloadBlobFile(exportRewardDormTemplate(), '文明宿舍导入模板.xlsx');
|
||||
};
|
||||
|
||||
// 文件变化
|
||||
const handleFileChange = (file: any) => {
|
||||
importFile.value = file.raw;
|
||||
};
|
||||
|
||||
// 提交导入
|
||||
const handleImportSubmit = async () => {
|
||||
if (!importFile.value) {
|
||||
useMessage().warning('请先选择要上传的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
importLoading.value = true;
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('file', importFile.value);
|
||||
await importRewardDorm(formData);
|
||||
useMessage().success('导入成功');
|
||||
importDialogVisible.value = false;
|
||||
importFile.value = null;
|
||||
uploadRef.value?.clearFiles();
|
||||
getDataList();
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败');
|
||||
} finally {
|
||||
importLoading.value = false;
|
||||
if (uploadExcelRef.value) {
|
||||
uploadExcelRef.value.show();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -206,33 +206,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RewardStudent">
|
||||
import { reactive, ref, onMounted, computed, nextTick } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { fetchList, exportExcel, updateStuAward, getStuRewardList, getRewardRuleList } from '/@/api/stuwork/rewardstudent';
|
||||
import { getDeptList } from '/@/api/basic/basicclass';
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear';
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { parseTime } from '/@/utils/formatTime';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import {
|
||||
List,
|
||||
OfficeBuilding,
|
||||
Grid,
|
||||
CreditCard,
|
||||
Avatar,
|
||||
DataAnalysis,
|
||||
Warning,
|
||||
Trophy,
|
||||
Clock,
|
||||
Menu,
|
||||
Search,
|
||||
Document,
|
||||
Setting,
|
||||
View,
|
||||
} from '@element-plus/icons-vue';
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
import { reactive, ref, onMounted, computed, nextTick } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { fetchList, updateStuAward, getStuRewardList, getRewardRuleList } from "/@/api/stuwork/rewardstudent";
|
||||
import { makeExportStudentPraiseTask } from "/@/api/stuwork/file";
|
||||
import { getDeptList } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import { parseTime } from "/@/utils/formatTime";
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
import { List, OfficeBuilding, Grid, CreditCard, Avatar, DataAnalysis, Warning, Trophy, Clock, Menu, Search, Document, Setting, View } from '@element-plus/icons-vue'
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn'
|
||||
|
||||
const dateTimeFormat = '{y}-{m}-{d} {h}:{i}:{s}';
|
||||
|
||||
@@ -352,38 +338,15 @@ const handleReset = () => {
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await exportExcel(queryForm);
|
||||
|
||||
// 创建 blob
|
||||
const blob = new Blob([res], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
});
|
||||
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
|
||||
// 设置文件名
|
||||
const fileName = `奖励学生_${new Date().getTime()}.xlsx`;
|
||||
link.setAttribute('download', fileName);
|
||||
|
||||
// 触发下载
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
|
||||
// 清理
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
|
||||
useMessage().success('导出成功');
|
||||
loading.value = true
|
||||
await makeExportStudentPraiseTask(queryForm)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败');
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
} finally {
|
||||
loading.value = false;
|
||||
loading.value = false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
|
||||
@@ -64,7 +64,9 @@
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<el-button icon="Plus" type="primary" @click="formDialogRef.openDialog()"> 新增 </el-button>
|
||||
<el-button icon="Upload" type="success" class="ml10" @click="handleImport"> 导入 </el-button>
|
||||
<el-button icon="Upload" type="success" class="ml10" @click="handleImport"> 导入行为记录 </el-button>
|
||||
<el-button icon="Download" type="primary" plain class="ml10" @click="handleDownloadConductTemplate"> 导入考核模板 </el-button>
|
||||
<el-button icon="Upload" type="warning" class="ml10" @click="handleConductImport"> 导入考核 </el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList">
|
||||
<TableColumnControl
|
||||
ref="columnControlRef"
|
||||
@@ -167,7 +169,7 @@
|
||||
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 导入对话框 -->
|
||||
<el-dialog title="导入数据" v-model="importDialogVisible" :width="500" :close-on-click-modal="false" draggable>
|
||||
<el-dialog title="导入行为记录" v-model="importDialogVisible" :width="500" :close-on-click-modal="false" draggable>
|
||||
<el-upload ref="uploadRef" :auto-upload="false" :on-change="handleFileChange" :limit="1" accept=".xlsx,.xls" drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
@@ -182,6 +184,26 @@
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 导入操行考核弹窗 -->
|
||||
<el-dialog title="导入操行考核数据" v-model="conductImportDialogVisible" :width="500" :close-on-click-modal="false" draggable>
|
||||
<div style="margin-bottom: 15px">
|
||||
<el-button icon="Download" type="success" @click="handleDownloadConductTemplate"> 下载模板 </el-button>
|
||||
</div>
|
||||
<el-upload :auto-upload="false" :on-change="handleConductFileChange" :limit="1" accept=".xlsx,.xls" drag>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">只能上传 xlsx/xls 文件,请先下载导入模板</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="conductImportDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleConductImportSubmit" :disabled="!conductImportFile || conductImportLoading">确认导入</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -190,6 +212,7 @@ import { reactive, ref, onMounted, computed, nextTick } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, delObj, importExcel } from '/@/api/stuwork/stuconduct';
|
||||
import { exportConductAssessmentTemplate, importConductAssessment, downloadBlobFile } from '/@/api/stuwork/file';
|
||||
import { getDeptList } from '/@/api/basic/basicclass';
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear';
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass';
|
||||
@@ -230,6 +253,9 @@ const typeList = ref<any[]>([]);
|
||||
const importDialogVisible = ref(false);
|
||||
const importFile = ref<File | null>(null);
|
||||
const importLoading = ref(false);
|
||||
const conductImportDialogVisible = ref(false);
|
||||
const conductImportFile = ref<File | null>(null);
|
||||
const conductImportLoading = ref(false);
|
||||
|
||||
// 表格列配置
|
||||
const tableColumns = [
|
||||
@@ -365,6 +391,49 @@ const handleImportSubmit = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 下载操行考核导入模板
|
||||
const handleDownloadConductTemplate = async () => {
|
||||
try {
|
||||
await downloadBlobFile(exportConductAssessmentTemplate(), `操行考核导入模板_${Date.now()}.xlsx`);
|
||||
} catch (err: any) {
|
||||
useMessage().error(err?.msg || '下载模板失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 打开操行考核导入弹窗
|
||||
const handleConductImport = () => {
|
||||
conductImportDialogVisible.value = true;
|
||||
conductImportFile.value = null;
|
||||
};
|
||||
|
||||
// 操行考核文件变化
|
||||
const handleConductFileChange = (file: any) => {
|
||||
conductImportFile.value = file.raw;
|
||||
};
|
||||
|
||||
// 提交操行考核导入
|
||||
const handleConductImportSubmit = async () => {
|
||||
if (!conductImportFile.value) {
|
||||
useMessage().warning('请先选择要上传的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
conductImportLoading.value = true;
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('file', conductImportFile.value);
|
||||
await importConductAssessment(formData);
|
||||
useMessage().success('导入成功');
|
||||
conductImportDialogVisible.value = false;
|
||||
conductImportFile.value = null;
|
||||
getDataList();
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导入失败');
|
||||
} finally {
|
||||
conductImportLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row);
|
||||
|
||||
@@ -5,18 +5,47 @@
|
||||
<el-row v-show="showSearch">
|
||||
<el-form :model="queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="学年" prop="schoolYear">
|
||||
<el-select v-model="queryForm.schoolYear" placeholder="请选择学年" clearable filterable style="width: 200px">
|
||||
<el-option v-for="item in schoolYearList" :key="item.year" :label="item.year" :value="item.year"> </el-option>
|
||||
<el-select
|
||||
v-model="queryForm.schoolYear"
|
||||
placeholder="请选择学年"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolYearList"
|
||||
:key="item.year"
|
||||
:label="item.year"
|
||||
:value="item.year">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="学期" prop="schoolTerm">
|
||||
<el-select v-model="queryForm.schoolTerm" placeholder="请选择学期" clearable style="width: 200px">
|
||||
<el-option v-for="item in schoolTermList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
<el-select
|
||||
v-model="queryForm.schoolTerm"
|
||||
placeholder="请选择学期"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in schoolTermList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="班级" prop="classCode">
|
||||
<el-select v-model="queryForm.classCode" placeholder="请选择班级" clearable filterable style="width: 200px">
|
||||
<el-option v-for="item in classList" :key="item.classCode" :label="item.classNo" :value="item.classCode"> </el-option>
|
||||
<el-select
|
||||
v-model="queryForm.classCode"
|
||||
placeholder="请选择班级"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 200px">
|
||||
<el-option
|
||||
v-for="item in classList"
|
||||
:key="item.classCode"
|
||||
:label="item.classNo"
|
||||
:value="item.classCode">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
@@ -74,7 +103,12 @@
|
||||
</div>
|
||||
|
||||
<!-- 查看详情弹窗(接口:queryDataByStuNo 通过学年学号查看详情,按当前学期筛选) -->
|
||||
<el-dialog v-model="viewDialogVisible" title="学期操行考核详情" width="800px" destroy-on-close @close="viewDetailList = []">
|
||||
<el-dialog
|
||||
v-model="viewDialogVisible"
|
||||
title="学期操行考核详情"
|
||||
width="800px"
|
||||
destroy-on-close
|
||||
@close="viewDetailList = []">
|
||||
<div v-if="viewRow" class="view-summary">
|
||||
<el-descriptions :column="2" border size="small">
|
||||
<el-descriptions-item label="学号">{{ viewRow.stuNo }}</el-descriptions-item>
|
||||
@@ -94,8 +128,7 @@
|
||||
size="small"
|
||||
max-height="400"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
:header-cell-style="tableStyle.headerCellStyle">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="schoolTerm" label="学期" width="80" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="recordDate" label="考核日期" width="110" align="center" show-overflow-tooltip />
|
||||
@@ -122,12 +155,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuConductTerm">
|
||||
import { reactive, ref, onMounted, computed } from 'vue';
|
||||
import { getStuConductTerm, queryDataByStuNo, sendConductWarning } from '/@/api/stuwork/stuconduct';
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass';
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import { reactive, ref, onMounted, computed } from 'vue'
|
||||
import { getStuConductTerm, queryDataByStuNo, sendConductWarning } from "/@/api/stuwork/stuconduct";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
|
||||
// 表格样式 - 在组件内部定义,不从外部导入
|
||||
const tableStyle = {
|
||||
@@ -136,18 +169,18 @@ const tableStyle = {
|
||||
};
|
||||
|
||||
// 定义变量内容
|
||||
const searchFormRef = ref();
|
||||
const showSearch = ref(true);
|
||||
const loading = ref(false);
|
||||
const warningLoading = ref(false);
|
||||
const schoolYearList = ref<any[]>([]);
|
||||
const schoolTermList = ref<any[]>([]);
|
||||
const classList = ref<any[]>([]);
|
||||
const studentList = ref<any[]>([]);
|
||||
const viewDialogVisible = ref(false);
|
||||
const viewLoading = ref(false);
|
||||
const viewRow = ref<any>(null);
|
||||
const viewDetailList = ref<any[]>([]);
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const loading = ref(false)
|
||||
const warningLoading = ref(false)
|
||||
const schoolYearList = ref<any[]>([])
|
||||
const schoolTermList = ref<any[]>([])
|
||||
const classList = ref<any[]>([])
|
||||
const studentList = ref<any[]>([])
|
||||
const viewDialogVisible = ref(false)
|
||||
const viewLoading = ref(false)
|
||||
const viewRow = ref<any>(null)
|
||||
const viewDetailList = ref<any[]>([])
|
||||
|
||||
// 查询表单
|
||||
const queryForm = reactive({
|
||||
|
||||
@@ -254,34 +254,20 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuLeaveApply">
|
||||
import { reactive, ref, onMounted, computed, nextTick } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, exportData, cancelObj } from '/@/api/stuwork/stuleaveapply';
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { getDeptListByLevelTwo } from '/@/api/basic/basicdept';
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import FormDialog from './form.vue';
|
||||
import {
|
||||
List,
|
||||
Calendar,
|
||||
Clock,
|
||||
OfficeBuilding,
|
||||
Avatar,
|
||||
Collection,
|
||||
Document,
|
||||
House,
|
||||
Warning,
|
||||
CircleCheck,
|
||||
EditPen,
|
||||
Setting,
|
||||
Menu,
|
||||
Search,
|
||||
} from '@element-plus/icons-vue';
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
import { reactive, ref, onMounted, computed, nextTick } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, cancelObj } from "/@/api/stuwork/stuleaveapply";
|
||||
import { makeExportStudentLeaveTask } from "/@/api/stuwork/file";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { getDeptListByLevelTwo } from "/@/api/basic/basicdept";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
import FormDialog from './form.vue'
|
||||
import { List, Calendar, Clock, OfficeBuilding, Avatar, Collection, Document, House, Warning, CircleCheck, EditPen, Setting, Menu, Search } from '@element-plus/icons-vue'
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn'
|
||||
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
const StatusTag = defineAsyncComponent(() => import('/@/components/StatusTag/index.vue'));
|
||||
@@ -449,22 +435,12 @@ const handleCancel = async (row: any) => {
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const res = await exportData(searchForm);
|
||||
// 处理返回的文件流
|
||||
const blob = new Blob([res.data]);
|
||||
const elink = document.createElement('a');
|
||||
elink.download = '学生请假.xlsx';
|
||||
elink.style.display = 'none';
|
||||
elink.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
useMessage().success('导出成功');
|
||||
await makeExportStudentLeaveTask(searchForm)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败');
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
|
||||
@@ -191,33 +191,20 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StuPunlish">
|
||||
import { reactive, ref, onMounted, computed, nextTick } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, delObj, exportData, revokePunishment, getDetail } from '/@/api/stuwork/stupunlish';
|
||||
import { queryAllSchoolYear } from '/@/api/basic/basicyear';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { getDeptListByLevelTwo } from '/@/api/basic/basicdept';
|
||||
import { getClassListByRole } from '/@/api/basic/basicclass';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
import FormDialog from './form.vue';
|
||||
import {
|
||||
List,
|
||||
Calendar,
|
||||
Clock,
|
||||
OfficeBuilding,
|
||||
Grid,
|
||||
Avatar,
|
||||
CreditCard,
|
||||
Warning,
|
||||
Document,
|
||||
CircleCheck,
|
||||
Setting,
|
||||
Menu,
|
||||
Search,
|
||||
} from '@element-plus/icons-vue';
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
import { reactive, ref, onMounted, computed, nextTick } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, revokePunishment, getDetail } from "/@/api/stuwork/stupunlish";
|
||||
import { makeExportStudentDisciplineTask } from "/@/api/stuwork/file";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { getDeptListByLevelTwo } from "/@/api/basic/basicdept";
|
||||
import { getClassListByRole } from "/@/api/basic/basicclass";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
import FormDialog from './form.vue'
|
||||
import { List, Calendar, Clock, OfficeBuilding, Grid, Avatar, CreditCard, Warning, Document, CircleCheck, Setting, Menu, Search } from '@element-plus/icons-vue'
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn'
|
||||
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
const StatusTag = defineAsyncComponent(() => import('/@/components/StatusTag/index.vue'));
|
||||
@@ -414,30 +401,20 @@ const handleCancel = async (row: any) => {
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const params: any = { ...searchForm };
|
||||
const params: any = { ...searchForm }
|
||||
// 处理处分月份参数 API
|
||||
if (params.punlishMonth) {
|
||||
params.punlishMonth = [params.punlishMonth];
|
||||
params.punlishMonth = [params.punlishMonth]
|
||||
} else {
|
||||
delete params.punlishMonth;
|
||||
delete params.punlishMonth
|
||||
}
|
||||
delete params.punlishMonthArray;
|
||||
const res = await exportData(params);
|
||||
// 下载文件
|
||||
const blob = new Blob([res.data]);
|
||||
const elink = document.createElement('a');
|
||||
elink.download = '学生处分.xlsx';
|
||||
elink.style.display = 'none';
|
||||
elink.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
useMessage().success('导出成功');
|
||||
delete params.punlishMonthArray
|
||||
await makeExportStudentDisciplineTask(params)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败');
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 获取学年列表
|
||||
const getSchoolYearList = async () => {
|
||||
|
||||
@@ -257,7 +257,8 @@
|
||||
import { reactive, ref, onMounted, computed, nextTick } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObj, exportData, cancelObj } from "/@/api/stuwork/stuturnover";
|
||||
import { fetchList, delObj, cancelObj } from "/@/api/stuwork/stuturnover";
|
||||
import { makeExportStudentChangeTask } from "/@/api/stuwork/file";
|
||||
import { queryAllSchoolYear } from "/@/api/basic/basicyear";
|
||||
import { getDicts } from "/@/api/admin/dict";
|
||||
import { getDeptListByLevelTwo } from "/@/api/basic/basicdept";
|
||||
@@ -438,18 +439,8 @@ const handleDelete = async (row: any) => {
|
||||
// 导出
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const res = await exportData(searchForm)
|
||||
// 处理返回的文件流
|
||||
const blob = new Blob([res.data])
|
||||
const elink = document.createElement('a')
|
||||
elink.download = '学籍异动.xlsx'
|
||||
elink.style.display = 'none'
|
||||
elink.href = URL.createObjectURL(blob)
|
||||
document.body.appendChild(elink)
|
||||
elink.click()
|
||||
URL.revokeObjectURL(elink.href)
|
||||
document.body.removeChild(elink)
|
||||
useMessage().success('导出成功')
|
||||
await makeExportStudentChangeTask(searchForm)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
|
||||
@@ -272,6 +272,7 @@ import { reactive, ref, onMounted, computed, nextTick } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { fetchList, delObjs, initWaterOrder } from "/@/api/stuwork/waterdetail";
|
||||
import { makeExportDormWaterElectricityTask } from "/@/api/stuwork/file";
|
||||
import { getBuildingList } from "/@/api/stuwork/dormbuilding";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
@@ -410,9 +411,13 @@ const handleDelete = async (row: any) => {
|
||||
}
|
||||
|
||||
// 导出
|
||||
const handleExport = () => {
|
||||
// TODO: 实现导出
|
||||
useMessage().warning('功能开发中')
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
await makeExportDormWaterElectricityTask(searchForm)
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载')
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '导出失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 统计分析
|
||||
|
||||
Reference in New Issue
Block a user