feat: 参数配置教师应用和切换学生功能

This commit is contained in:
TsMask
2024-07-17 17:03:32 +08:00
parent cfd04ba1b6
commit c87458bc23
3 changed files with 158 additions and 96 deletions

View File

@@ -1,14 +0,0 @@
import { request } from '@/plugins/http-fetch';
/**
* 班级学生列表 (仅教师操作)
* @param params 数据 {neType,paramName}
* @returns object
*/
export function getPtClassStudents(params: Record<string, any>) {
return request({
url: `/pt/class/students`,
params,
method: 'get',
});
}

View File

@@ -1,97 +1,130 @@
import { getPtClassStudents } from '@/api/pt/neClass';
import { ptSaveAsDefault, ptResetAsDefault } from '@/api/pt/neConfig'; import { ptSaveAsDefault, ptResetAsDefault } from '@/api/pt/neConfig';
import { stuPtNeConfigApply } from '@/api/pt/neConfigApply'; import {
getPtClassStudents,
stuPtNeConfigApply,
updatePtNeConfigApply,
} from '@/api/pt/neConfigApply';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { hasRoles } from '@/plugins/auth-user'; import { hasRoles } from '@/plugins/auth-user';
import { message } from 'ant-design-vue/lib'; import { message } from 'ant-design-vue/lib';
import { onMounted, reactive } from 'vue'; import { computed, onMounted, reactive, ref } from 'vue';
/** /**
* 实训教学函数 * 实训教学函数
* @param param 父级传入 {t} * @param param 父级传入 {t,fnActiveConfigNode}
* @returns * @returns
*/ */
export default function usePtOptions({ t }: any) { export default function usePtOptions({ t, fnActiveConfigNode }: any) {
const ptConfigState = reactive({
saveLoading: false,
restLoading: false,
applyLoading: false,
});
/**保存网元下所有配置为示例配置 */ /**保存网元下所有配置为示例配置 */
function ptConfigSave(neType: string) { function ptConfigSave(neType: string) {
ptSaveAsDefault(neType, '001').then(res => { ptConfigState.saveLoading = true;
if (res.code === RESULT_CODE_SUCCESS) { ptSaveAsDefault(neType, '001')
message.success({ .then(res => {
content: t('common.operateOk'), if (res.code === RESULT_CODE_SUCCESS) {
duration: 3, message.success({
}); content: t('common.operateOk'),
} else { duration: 3,
message.error({ });
content: `${res.msg}`, } else {
duration: 3, message.error({
}); content: `${res.msg}`,
} duration: 3,
}); });
}
})
.finally(() => {
ptConfigState.saveLoading = false;
});
} }
/**重置网元下所有配置 */ /**重置网元下所有配置 */
function ptConfigReset(neType: string) { function ptConfigReset(neType: string) {
ptResetAsDefault(neType).then(res => { ptConfigState.restLoading = true;
if (res.code === RESULT_CODE_SUCCESS) { ptResetAsDefault(neType)
message.success({ .then(res => {
content: t('common.operateOk'), if (res.code === RESULT_CODE_SUCCESS) {
duration: 3, message.success({
}); content: t('common.operateOk'),
} else { duration: 3,
message.error({ });
content: `${res.msg}`, } else {
duration: 3, message.error({
}); content: `${res.msg}`,
} duration: 3,
}); });
}
})
.finally(() => {
ptConfigState.restLoading = false;
fnActiveConfigNode('#');
});
} }
/**配置下方应用申请和撤回 */ /**配置下方应用(学生)申请撤回和(管理/教师)应用退回 */
function ptConfigApply(neType: string, status: string) { function ptConfigApply(neType: string, status: '0' | '1' |'2'| '3' ) {
stuPtNeConfigApply({ neType, status }).then(res => { let result: any;
if (res.code === RESULT_CODE_SUCCESS) { if (status === '2') {
message.success({ result = updatePtNeConfigApply({ neType, status: '2' });
content: t('common.operateOk'), }
duration: 3, if (status === '0') {
}); result = stuPtNeConfigApply({ neType, status: '0' });
} else { }
message.error({ if (!result) return;
content: `${res.msg}`, ptConfigState.applyLoading = true;
duration: 3, result
}); .then((res: any) => {
} if (res.code === RESULT_CODE_SUCCESS) {
}); message.success({
content: t('common.operateOk'),
duration: 3,
});
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
}
})
.finally(() => {
ptConfigState.applyLoading = false;
});
} }
const classState = reactive<{ const classState = reactive<{
/**学生账号 */ /**学生账号 */
student: string | undefined; student: string | undefined;
/**学生可选择列表 */ /**学生可选择列表 */
studentOptions: { value: string; label: string }[]; studentOptions: { value: string; label: string; status: string }[];
studentOptionsDef: { value: string; label: string }[]; studentOptionsDef: { value: string; label: string; status: string }[];
}>({ }>({
student: undefined, student: undefined,
studentOptions: [], studentOptions: [],
studentOptionsDef: [], studentOptionsDef: [],
}); });
/**初始学生列表 */ // 仅教师加载
function initStudentList() { if (hasRoles(['teacher'])) {
getPtClassStudents({ onMounted(() => {
pageNum: 1, // 初始学生列表
pageSize: 60, getPtClassStudents().then(res => {
}).then(res => { if (!Array.isArray(res.data) || res.data.length <= 0) {
if (!Array.isArray(res.rows) || res.rows.length <= 0) { return;
return; }
} classState.studentOptions = [];
classState.studentOptions = []; for (const s of res.data) {
for (const s of res.rows) { classState.studentOptions.push({
classState.studentOptions.push({ value: s.userName,
value: s.userName, label: s.userName,
label: s.userName, status: s.applyStatus,
}); });
} }
Object.assign(classState.studentOptionsDef, classState.studentOptions); Object.assign(classState.studentOptionsDef, classState.studentOptions);
});
}); });
} }
@@ -108,16 +141,13 @@ export default function usePtOptions({ t }: any) {
return; return;
} }
function fake() { function fake() {
getPtClassStudents({ getPtClassStudents({ userName: val }).then(res => {
userName: val,
pageNum: 1,
pageSize: 10,
}).then(res => {
classState.studentOptions = []; classState.studentOptions = [];
for (const s of res.rows) { for (const s of res.data) {
classState.studentOptions.push({ classState.studentOptions.push({
value: s.userName, value: s.userName,
label: s.userName, label: s.userName,
status: s.applyStatus,
}); });
} }
}); });
@@ -125,18 +155,23 @@ export default function usePtOptions({ t }: any) {
timeout = setTimeout(fake, 500); timeout = setTimeout(fake, 500);
} }
// 仅教师加载
if (hasRoles(['teacher'])) { // 学生状态
onMounted(() => { const studentStatus = computed(() => {
initStudentList(); const item = classState.studentOptions.find(
}); s => s.value === classState.student
} );
if (item) return item.status;
return '';
});
return { return {
ptConfigState,
ptConfigSave, ptConfigSave,
ptConfigReset, ptConfigReset,
ptConfigApply, ptConfigApply,
classState, classState,
studentStatus,
studentSearch, studentSearch,
}; };
} }

View File

@@ -2,6 +2,7 @@
import { reactive, ref, onMounted, toRaw, watch } from 'vue'; import { reactive, ref, onMounted, toRaw, watch } from 'vue';
import { PageContainer } from 'antdv-pro-layout'; import { PageContainer } from 'antdv-pro-layout';
import { message } from 'ant-design-vue/lib'; import { message } from 'ant-design-vue/lib';
import { DataNode } from 'ant-design-vue/lib/tree';
import useI18n from '@/hooks/useI18n'; import useI18n from '@/hooks/useI18n';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue'; import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
@@ -11,7 +12,6 @@ import usePtOptions from './hooks/usePtOptions';
import useConfigList from './hooks/useConfigList'; import useConfigList from './hooks/useConfigList';
import useConfigArray from './hooks/useConfigArray'; import useConfigArray from './hooks/useConfigArray';
import useConfigArrayChild from './hooks/useConfigArrayChild'; import useConfigArrayChild from './hooks/useConfigArrayChild';
import { DataNode } from 'ant-design-vue/lib/tree';
import { getAllNeConfig } from '@/api/ne/neConfig'; import { getAllNeConfig } from '@/api/ne/neConfig';
import { getPtNeConfigData } from '@/api/pt/neConfig'; import { getPtNeConfigData } from '@/api/pt/neConfig';
import { hasRoles } from '@/plugins/auth-user'; import { hasRoles } from '@/plugins/auth-user';
@@ -329,12 +329,14 @@ watch(
); );
const { const {
ptConfigState,
ptConfigSave, ptConfigSave,
ptConfigReset, ptConfigReset,
ptConfigApply, ptConfigApply,
classState, classState,
studentStatus,
studentSearch, studentSearch,
} = usePtOptions({ t, treeState }); } = usePtOptions({ t, fnActiveConfigNode });
const { tablePagination, listState, listEdit, listEditClose, listEditOk } = const { tablePagination, listState, listEdit, listEditClose, listEditOk } =
useConfigList({ t, treeState, ruleVerification }); useConfigList({ t, treeState, ruleVerification });
@@ -437,38 +439,77 @@ onMounted(() => {
:options="classState.studentOptions" :options="classState.studentOptions"
@search="studentSearch" @search="studentSearch"
@change="fnActiveConfigNode('#')" @change="fnActiveConfigNode('#')"
></a-select> >
<template #option="{ value, label, status }">
<span>{{ label }} </span>
<a-tag
v-if="status === '0'"
color="processing"
style="position: absolute; right: 0;}"
>
{{ status && '申请' }}
</a-tag>
</template>
</a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :lg="6" :md="12" :xs="24"> <a-col :lg="6" :md="12" :xs="24">
<a-form-item> <a-form-item>
<a-space :size="8"> <a-space :size="8">
<template
v-if="
hasRoles(['teacher']) &&
classState.student &&
studentStatus === '0'
"
>
<a-button
@click="ptConfigApply(treeState.neType, '2')"
:loading="ptConfigState.applyLoading"
>
应用
</a-button>
<a-button
@click="ptConfigApply(treeState.neType, '3')"
:loading="ptConfigState.applyLoading"
>
退回
</a-button>
</template>
<a-button <a-button
v-roles:has="['admin', 'teacher']" v-roles:has="['admin', 'teacher']"
:disabled="!!classState.student" v-show="!classState.student"
@click="ptConfigApply(treeState.neType, '2')"
:loading="ptConfigState.applyLoading"
> >
(管理员/教师) 应用到网元 (管理员/教师) 应用到网元
</a-button> </a-button>
<a-button <a-button
@click="ptConfigSave(treeState.neType)" @click="ptConfigSave(treeState.neType)"
:loading="ptConfigState.saveLoading"
v-roles:has="['admin']" v-roles:has="['admin']"
> >
(管理员)载入网元配置为系统示例 (管理员)载入网元配置为系统示例
</a-button> </a-button>
<a-button <a-button
@click="ptConfigReset(treeState.neType)" @click="ptConfigReset(treeState.neType)"
v-show="!classState.student"
:loading="ptConfigState.restLoading"
v-roles:has="['teacher']" v-roles:has="['teacher']"
> >
(教师)重置为系统示例 (教师)重置为系统示例
</a-button> </a-button>
<a-button <a-button
@click="ptConfigReset(treeState.neType)" @click="ptConfigReset(treeState.neType)"
:loading="ptConfigState.restLoading"
v-roles:has="['student']" v-roles:has="['student']"
> >
(学生)重置为教师示例 (学生)重置为教师示例
</a-button> </a-button>
<a-button <a-button
@click="ptConfigApply(treeState.neType, '0')" @click="ptConfigApply(treeState.neType, '0')"
:loading="ptConfigState.applyLoading"
v-roles:has="['student']" v-roles:has="['student']"
> >
(学生)申请应用到 {{ treeState.neType }} (学生)申请应用到 {{ treeState.neType }}