feat: 添加导出所有学生配置功能,优化提示信息

This commit is contained in:
TsMask
2025-03-08 10:31:54 +08:00
parent 0cb892e7f3
commit 20007f4732
14 changed files with 1067 additions and 1107 deletions

View File

@@ -5,9 +5,9 @@ import {
updatePtNeConfigApply,
} from '@/api/pt/neConfigApply';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { hasRoles } from '@/plugins/auth-user';
import { Modal } from 'ant-design-vue/es';
import { message } from 'ant-design-vue/lib';
import { computed, onMounted, reactive } from 'vue';
import { computed, reactive } from 'vue';
/**
* 实训教学函数
@@ -22,48 +22,60 @@ export default function usePtOptions({ t, fnActiveConfigNode }: any) {
});
/**(管理员)保存网元下所有配置为示例配置 */
function ptConfigSave(neType: string) {
ptConfigState.saveLoading = true;
ptSaveAsDefault(neType, '001')
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 3,
Modal.confirm({
title: t('common.tipTitle'),
content: t('views.configManage.configParamForm.ptLoadTip'),
onOk() {
ptConfigState.saveLoading = true;
ptSaveAsDefault(neType, '001')
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 3,
});
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
}
})
.finally(() => {
ptConfigState.saveLoading = false;
fnActiveConfigNode('#');
});
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
}
})
.finally(() => {
ptConfigState.saveLoading = false;
fnActiveConfigNode('#');
});
},
});
}
/**重置网元下所有配置 */
function ptConfigReset(neType: string) {
ptConfigState.restLoading = true;
ptResetAsDefault(neType)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 3,
Modal.confirm({
title: t('common.tipTitle'),
content: t('views.configManage.configParamForm.ptResetTip'),
onOk() {
ptConfigState.restLoading = true;
ptResetAsDefault(neType)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 3,
});
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
}
})
.finally(() => {
ptConfigState.restLoading = false;
fnActiveConfigNode('#');
});
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
}
})
.finally(() => {
ptConfigState.restLoading = false;
fnActiveConfigNode('#');
});
},
});
}
/**配置下方应用(学生)申请撤回和(管理/教师)应用退回 */
@@ -97,33 +109,42 @@ export default function usePtOptions({ t, fnActiveConfigNode }: any) {
result = stuPtNeConfigApply({ neType, status });
}
if (!result) return;
ptConfigState.applyLoading = true;
result
.then((res: any) => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 3,
});
// 教师修改学生时改变状态
if (student) {
const item = classState.studentOptionsDef.find(
s => s.value === classState.student
);
if (item) {
item.applyStatus = status;
Modal.confirm({
title: t('common.tipTitle'),
content: t('views.configManage.configParamForm.ptApplyStuTip', {
ne: neType,
}),
onOk() {
ptConfigState.applyLoading = true;
result
.then((res: any) => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 3,
});
// 教师修改学生时改变状态
if (student) {
const item = classState.studentOptionsDef.find(
s => s.value === classState.student
);
if (item) {
item.applyStatus = status;
}
}
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
}
}
} else {
message.error({
content: `${res.msg}`,
duration: 3,
})
.finally(() => {
ptConfigState.applyLoading = false;
});
}
})
.finally(() => {
ptConfigState.applyLoading = false;
});
},
});
}
const classState = reactive<{
@@ -148,13 +169,6 @@ export default function usePtOptions({ t, fnActiveConfigNode }: any) {
studentOptionsDef: [],
});
// 仅教师加载
if (hasRoles(['teacher'])) {
onMounted(() => {
classStudents(); // 初始学生列表
});
}
/**学生选择搜索 */
function studentChange(v: any) {
if (!v) {
@@ -166,7 +180,7 @@ export default function usePtOptions({ t, fnActiveConfigNode }: any) {
let timeout: any;
/**学生选择搜索 */
function studentSearch(val: string) {
function studentSearch(neType: string, val: string) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
@@ -175,12 +189,12 @@ export default function usePtOptions({ t, fnActiveConfigNode }: any) {
Object.assign(classState.studentOptions, classState.studentOptionsDef);
return;
}
timeout = setTimeout(() => classStudents(val), 500);
timeout = setTimeout(() => classStudents(neType, val), 500);
}
/**班级学生列表 */
function classStudents(val?: string) {
getPtClassStudents({ userName: val }).then(res => {
function classStudents(neType: string, val?: string) {
getPtClassStudents({ neType, userName: val }).then(res => {
classState.studentOptions = [];
if (!Array.isArray(res.data) || res.data.length <= 0) {
return;
@@ -221,6 +235,7 @@ export default function usePtOptions({ t, fnActiveConfigNode }: any) {
ptConfigReset,
ptConfigApply,
classState,
classStudents,
studentStatus,
studentSearch,
studentChange,

View File

@@ -1,5 +1,12 @@
<script setup lang="ts">
import { reactive, ref, onMounted, toRaw, watch, defineAsyncComponent } from 'vue';
import {
reactive,
ref,
onMounted,
toRaw,
watch,
defineAsyncComponent,
} from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { ProModal } from 'antdv-pro-modal';
import { message, Modal } from 'ant-design-vue/es';
@@ -18,8 +25,10 @@ import {
getPtNeConfigData,
ptContrastAsDefault,
ptExport,
ptExportAll,
} from '@/api/pt/neConfig';
import { isSystemAdmin, hasRoles } from '@/plugins/auth-user';const neInfoStore = useNeInfoStore();
import { isSystemAdmin, hasRoles } from '@/plugins/auth-user';
const neInfoStore = useNeInfoStore();
import saveAs from 'file-saver';
const { t } = useI18n();
const { ruleVerification, smfByUPFIdLoadData, smfByUPFIdOptions } = useOptions({
@@ -232,35 +241,42 @@ function fnGetNeConfig() {
treeState.loading = true;
// 获取数据
getAllNeConfig(neType).then(res => {
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
const arr = [];
for (const item of res.data) {
let paramPerms: string[] = [];
if (item.paramPerms) {
paramPerms = item.paramPerms.split(',');
} else {
paramPerms = ['post', 'put', 'delete'];
getAllNeConfig(neType)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
const arr = [];
for (const item of res.data) {
let paramPerms: string[] = [];
if (item.paramPerms) {
paramPerms = item.paramPerms.split(',');
} else {
paramPerms = ['post', 'put', 'delete'];
}
arr.push({
...item,
children: undefined,
title: item.paramDisplay,
key: item.paramName,
paramPerms,
});
}
treeState.data = arr;
treeState.loading = false;
// 取首个tag
if (res.data.length > 0) {
const item = JSON.parse(JSON.stringify(treeState.data[0]));
treeState.selectNode = item;
treeState.selectLoading = false;
fnActiveConfigNode(item.key);
}
arr.push({
...item,
children: undefined,
title: item.paramDisplay,
key: item.paramName,
paramPerms,
});
}
treeState.data = arr;
treeState.loading = false;
// 取首个tag
if (res.data.length > 0) {
const item = JSON.parse(JSON.stringify(treeState.data[0]));
treeState.selectNode = item;
treeState.selectLoading = false;
fnActiveConfigNode(item.key);
})
.finally(() => {
// 仅教师加载
if (hasRoles(['teacher'])) {
classStudents(neType);
}
}
});
});
}
/**对话框对象信息状态类型 */
@@ -344,6 +360,7 @@ const {
studentStatus,
studentSearch,
studentChange,
classStudents,
} = usePtOptions({ t, fnActiveConfigNode });
const { tablePagination, listState, listEdit, listEditClose, listEditOk } =
@@ -450,6 +467,35 @@ function fnDataExport() {
});
}
// 数据导出Excel
function fnDataExportAll() {
Modal.confirm({
title: t('common.tipTitle'),
content: t('views.configManage.configParamForm.ptExportTip'),
onOk() {
const hide = message.loading(t('common.loading'), 0);
ptExportAll()
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('common.operateOk'),
duration: 2,
});
saveAs(res.data, `students_config_data_${Date.now()}.zip`);
} else {
message.error({
content: `${res.msg}`,
duration: 2,
});
}
})
.finally(() => {
hide();
});
},
});
}
onMounted(() => {
// 获取网元网元列表
neInfoStore.fnNelist().then(res => {
@@ -500,7 +546,7 @@ onMounted(() => {
<a-col :lg="8" :md="12" :xs="24" v-roles:has="['teacher']">
<a-form-item
:label="t('views.configManage.configParamForm.ptApplyShow')"
name="neType "
name="student "
>
<a-select
v-model:value="classState.student"
@@ -512,7 +558,7 @@ onMounted(() => {
:filter-option="false"
:not-found-content="null"
:options="classState.studentOptions"
@search="studentSearch"
@search="(v:any)=> studentSearch(treeState.neType, v)"
@change="studentChange"
>
<template #option="{ value, label, applyStatus }">
@@ -586,6 +632,9 @@ onMounted(() => {
<a-button @click="fnDataExport()" v-roles:has="['teacher']">
{{ t('views.configManage.configParamForm.ptExport') }}
</a-button>
<a-button @click="fnDataExportAll()" v-roles:has="['teacher']">
{{ t('views.configManage.configParamForm.ptExportAll') }}
</a-button>
<!-- 学生 -->
<a-button