feat: 实训教学模块

This commit is contained in:
TsMask
2024-11-23 11:18:40 +08:00
parent 2fb3467fb5
commit 285c9b660b
26 changed files with 16854 additions and 0 deletions

View File

@@ -0,0 +1,342 @@
import {
addPtNeConfigData,
delPtNeConfigData,
editPtNeConfigData,
} from '@/api/pt/neConfig';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import message from 'ant-design-vue/lib/message';
import { reactive, watch } from 'vue';
/**
* 参数配置array类型
* @param param 父级传入 { t, treeState, fnActiveConfigNode, ruleVerification, modalState, fnModalCancel}
* @returns
*/
export default function useConfigArray({
t,
treeState,
fnActiveConfigNode,
ruleVerification,
modalState,
fnModalCancel,
}: any) {
/**多列列表状态类型 */
type ArrayStateType = {
/**紧凑型 */
size: SizeType;
/**多列嵌套记录字段 */
columns: Record<string, any>[];
/**表格字段列排序 */
columnsDnd: Record<string, any>[];
/**多列记录数据 */
columnsData: Record<string, any>[];
/**多列嵌套展开key */
arrayChildExpandKeys: any[];
/**多列记录数据 */
data: Record<string, any>[];
/**多列记录规则 */
dataRule: Record<string, any>;
};
/**多列列表状态 */
let arrayState: ArrayStateType = reactive({
size: 'small',
columns: [],
columnsDnd: [],
columnsData: [],
arrayChildExpandKeys: [],
data: [],
dataRule: {},
});
/**多列表编辑 */
function arrayEdit(rowIndex: Record<string, any>) {
const item = arrayState.data.find((s: any) => s.key === rowIndex.value);
if (!item) return;
const from = arrayInitEdit(item, arrayState.dataRule);
// 处理信息
const row: Record<string, any> = {};
for (const v of from.record) {
if (Array.isArray(v.array)) {
continue;
}
row[v.name] = Object.assign({}, v);
}
modalState.from = row;
modalState.type = 'arrayEdit';
modalState.title = `${treeState.selectNode.paramDisplay} ${from.title}`;
modalState.key = from.key;
modalState.data = from.record.filter((v: any) => !Array.isArray(v.array));
modalState.open = true;
// 关闭嵌套
arrayState.arrayChildExpandKeys = [];
}
/**多列表编辑关闭 */
function arrayEditClose() {
arrayState.arrayChildExpandKeys = [];
fnModalCancel();
}
/**多列表编辑确认 */
function arrayEditOk(from: Record<string, any>) {
// 遍历提取属性和值
let data: Record<string, any> = {};
for (const key in from) {
// 子嵌套的不插入
if (from[key]['array']) {
continue;
}
// 检查规则
const [ok, msg] = ruleVerification(from[key]);
if (!ok) {
message.warning({
content: `${msg}`,
duration: 3,
});
return;
}
data[key] = from[key]['value'];
}
// 发送
const hide = message.loading(t('common.loading'), 0);
editPtNeConfigData({
neType: treeState.neType,
paramName: treeState.selectNode.paramName,
paramData: data,
loc: `${from['index']['value']}`,
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('views.configManage.configParamForm.updateItem', {
num: modalState.title,
}),
duration: 3,
});
fnActiveConfigNode('#');
} else {
message.warning({
content: t('views.configManage.configParamForm.updateItemErr'),
duration: 3,
});
}
})
.finally(() => {
hide();
arrayEditClose();
});
}
/**多列表删除单行 */
function arrayDelete(rowIndex: Record<string, any>) {
const loc = `${rowIndex.value}`;
const title = `${treeState.selectNode.paramDisplay} Index-${loc}`;
Modal.confirm({
title: t('common.tipTitle'),
content: t('views.configManage.configParamForm.delItemTip', {
num: title,
}),
onOk() {
delPtNeConfigData({
neType: treeState.neType,
paramName: treeState.selectNode.paramName,
loc: loc,
}).then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('views.configManage.configParamForm.delItemOk', {
num: title,
}),
duration: 2,
});
arrayEditClose();
fnActiveConfigNode('#');
} else {
message.error({
content: `${res.msg}`,
duration: 2,
});
}
});
},
});
}
/**多列表新增单行 */
function arrayAdd() {
const from = arrayInitAdd(arrayState.data, arrayState.dataRule);
// 处理信息
const row: Record<string, any> = {};
for (const v of from.record) {
if (Array.isArray(v.array)) {
continue;
}
row[v.name] = Object.assign({}, v);
}
modalState.from = row;
modalState.type = 'arrayAdd';
modalState.title = `${treeState.selectNode.paramDisplay} ${from.title}`;
modalState.key = from.key;
modalState.data = from.record.filter((v: any) => !Array.isArray(v.array));
modalState.open = true;
}
/**多列表新增单行确认 */
function arrayAddOk(from: Record<string, any>) {
// 遍历提取属性和值
let data: Record<string, any> = {};
for (const key in from) {
// 子嵌套的不插入
if (from[key]['array']) {
continue;
}
// 检查规则
const [ok, msg] = ruleVerification(from[key]);
if (!ok) {
message.warning({
content: `${msg}`,
duration: 3,
});
return;
}
data[key] = from[key]['value'];
}
// 发送
const hide = message.loading(t('common.loading'), 0);
addPtNeConfigData({
neType: treeState.neType,
paramName: treeState.selectNode.paramName,
paramData: data,
loc: `${from['index']['value']}`,
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('views.configManage.configParamForm.addItemOk', {
num: modalState.title,
}),
duration: 3,
});
fnActiveConfigNode('#');
} else {
message.warning({
content: t('views.configManage.configParamForm.addItemErr'),
duration: 3,
});
}
})
.finally(() => {
hide();
arrayEditClose();
});
}
/**多列表编辑行数据初始化 */
function arrayInitEdit(data: Record<string, any>, dataRule: any) {
const dataFrom = data.record;
const ruleFrom = Object.assign({}, JSON.parse(JSON.stringify(dataRule)));
for (const row of ruleFrom.record) {
// 子嵌套的不初始
if (row.array) {
row.value = [];
continue;
}
// 查找项的值
const item = dataFrom.find((s: any) => s.name === row.name);
if (!item) {
continue;
}
// 可选的
row.optional = 'true';
// 根据规则类型转值
if (['enum', 'int'].includes(row.type)) {
row.value = Number(item.value);
} else if ('bool' === row.type) {
row.value = Boolean(item.value);
} else {
row.value = item.value;
}
}
ruleFrom.key = data.key;
ruleFrom.title = data.title;
return ruleFrom;
}
/**多列表新增行数据初始化 */
function arrayInitAdd(data: any[], dataRule: any) {
// 有数据时取得最后的index
let dataLastIndex = 0;
if (data.length !== 0) {
const lastFrom = Object.assign(
{},
JSON.parse(JSON.stringify(data.at(-1)))
);
if (lastFrom.record.length > 0) {
dataLastIndex = parseInt(lastFrom.key);
dataLastIndex += 1;
}
}
const ruleFrom = Object.assign({}, JSON.parse(JSON.stringify(dataRule)));
for (const row of ruleFrom.record) {
// 子嵌套的不初始
if (row.array) {
row.value = [];
continue;
}
// 可选的
row.optional = 'true';
// index值
if (row.name === 'index') {
let newIndex =
dataLastIndex !== 0 ? dataLastIndex : parseInt(row.value);
if (isNaN(newIndex)) {
newIndex = 0;
}
row.value = newIndex;
ruleFrom.key = newIndex;
ruleFrom.title = `Index-${newIndex}`;
continue;
}
// 根据规则类型转值
if (['enum', 'int'].includes(row.type)) {
row.value = Number(row.value);
}
if ('bool' === row.type) {
row.value = Boolean(row.value);
}
}
return ruleFrom;
}
// 监听表格字段列排序变化关闭展开
watch(
() => arrayState.columnsDnd,
() => {
arrayEditClose();
}
);
return {
arrayState,
arrayEdit,
arrayEditClose,
arrayEditOk,
arrayDelete,
arrayAdd,
arrayAddOk,
arrayInitEdit,
arrayInitAdd,
};
}

View File

@@ -0,0 +1,349 @@
import {
addPtNeConfigData,
delPtNeConfigData,
editPtNeConfigData,
} from '@/api/pt/neConfig';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { Modal } from 'ant-design-vue/lib';
import { SizeType } from 'ant-design-vue/lib/config-provider';
import message from 'ant-design-vue/lib/message';
import { nextTick, reactive } from 'vue';
/**
* 参数配置array类型的嵌套array
* @param param 父级传入 { t, treeState, fnActiveConfigNode, ruleVerification, modalState, arrayState, arrayInitEdit, arrayInitAdd, arrayEditClose}
* @returns
*/
export default function useConfigArrayChild({
t,
treeState,
fnActiveConfigNode,
ruleVerification,
modalState,
arrayState,
arrayInitEdit,
arrayInitAdd,
arrayEditClose,
}: any) {
/**多列嵌套列表状态类型 */
type ArrayChildStateType = {
/**标题 */
title: string;
/**层级index */
loc: string;
/**紧凑型 */
size: SizeType;
/**多列嵌套记录字段 */
columns: Record<string, any>[];
/**表格字段列排序 */
columnsDnd: Record<string, any>[];
/**多列记录数据 */
columnsData: Record<string, any>[];
/**多列嵌套记录数据 */
data: Record<string, any>[];
/**多列嵌套记录规则 */
dataRule: Record<string, any>;
};
/**多列嵌套表格状态 */
let arrayChildState: ArrayChildStateType = reactive({
title: '',
loc: '',
size: 'small',
columns: [],
columnsDnd: [],
columnsData: [],
data: [],
dataRule: {},
});
/**多列表展开嵌套行 */
function arrayChildExpand(
indexRow: Record<string, any>,
row: Record<string, any>
) {
const loc = indexRow.value;
if (arrayChildState.loc === `${loc}/${row.name}`) {
arrayChildState.loc = '';
arrayState.arrayChildExpandKeys = [];
return;
}
arrayChildState.loc = '';
arrayState.arrayChildExpandKeys = [];
const from = Object.assign({}, JSON.parse(JSON.stringify(row)));
// 无数据时
if (!Array.isArray(from.value)) {
from.value = [];
}
const dataArr = Object.freeze(from.value);
const ruleArr = Object.freeze(from.array);
// 列表项数据
const dataArray: Record<string, any>[] = [];
for (const item of dataArr) {
const index = item['index'];
let record: Record<string, any>[] = [];
for (const key of Object.keys(item)) {
// 规则为准
for (const rule of ruleArr) {
if (rule['name'] === key) {
const ruleItem = Object.assign({ optional: 'true' }, rule, {
value: item[key],
});
record.push(ruleItem);
break;
}
}
}
// dataArray.push(record);
dataArray.push({ title: `Index-${index}`, key: index, record });
}
arrayChildState.data = dataArray;
// 无数据时,用于新增
arrayChildState.dataRule = {
title: `Index-0`,
key: 0,
record: ruleArr,
};
// 列表数据
const columnsData: Record<string, any>[] = [];
for (const v of arrayChildState.data) {
const row: Record<string, any> = {};
for (const item of v.record) {
row[item.name] = item;
}
columnsData.push(row);
}
arrayChildState.columnsData = columnsData;
// 列表字段
const columns: Record<string, any>[] = [];
for (const rule of arrayChildState.dataRule.record) {
columns.push({
title: rule.display,
dataIndex: rule.name,
align: 'left',
resizable: true,
width: 50,
minWidth: 50,
maxWidth: 250,
});
}
columns.push({
title: t('common.operate'),
dataIndex: 'index',
key: 'index',
align: 'center',
fixed: 'right',
width: 100,
});
arrayChildState.columns = columns;
nextTick(() => {
// 设置展开key
arrayState.arrayChildExpandKeys = [indexRow];
// 层级标识
arrayChildState.loc = `${loc}/${from['name']}`;
// 设置展开列表标题
arrayChildState.title = `${from['display']}`;
});
}
/**多列表嵌套行编辑 */
function arrayChildEdit(rowIndex: Record<string, any>) {
const item = arrayChildState.data.find(
(s: any) => s.key === rowIndex.value
);
if (!item) return;
const from = arrayInitEdit(item, arrayChildState.dataRule);
// 处理信息
const row: Record<string, any> = {};
for (const v of from.record) {
if (Array.isArray(v.array)) {
continue;
}
row[v.name] = Object.assign({}, v);
}
modalState.from = row;
modalState.type = 'arrayChildEdit';
modalState.title = `${arrayChildState.title} ${from.title}`;
modalState.key = from.key;
modalState.data = from.record.filter((v: any) => !Array.isArray(v.array));
modalState.open = true;
}
/**多列表嵌套行编辑确认 */
function arrayChildEditOk(from: Record<string, any>) {
const loc = `${arrayChildState.loc}/${from['index']['value']}`;
let data: Record<string, any> = {};
for (const key in from) {
// 子嵌套的不插入
if (from[key]['array']) {
continue;
}
// 检查规则
const [ok, msg] = ruleVerification(from[key]);
if (!ok) {
message.warning({
content: `${msg}`,
duration: 3,
});
return;
}
data[key] = from[key]['value'];
}
// 发送
const hide = message.loading(t('common.loading'), 0);
editPtNeConfigData({
neType: treeState.neType,
paramName: treeState.selectNode.paramName,
paramData: data,
loc,
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('views.configManage.configParamForm.updateItem', {
num: modalState.title,
}),
duration: 3,
});
fnActiveConfigNode('#');
} else {
message.warning({
content: t('views.configManage.configParamForm.updateItemErr'),
duration: 3,
});
}
})
.finally(() => {
hide();
arrayEditClose();
});
}
/**多列表嵌套行删除单行 */
function arrayChildDelete(rowIndex: Record<string, any>) {
const index = rowIndex.value;
const loc = `${arrayChildState.loc}/${index}`;
const title = `${arrayChildState.title} Index-${index}`;
Modal.confirm({
title: t('common.tipTitle'),
content: t('views.configManage.configParamForm.delItemTip', {
num: title,
}),
onOk() {
delPtNeConfigData({
neType: treeState.neType,
paramName: treeState.selectNode.paramName,
loc,
}).then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('views.configManage.configParamForm.delItemOk', {
num: title,
}),
duration: 2,
});
arrayEditClose();
fnActiveConfigNode('#');
} else {
message.error({
content: `${res.msg}`,
duration: 2,
});
}
});
},
});
}
/**多列表嵌套行新增单行 */
function arrayChildAdd() {
const from = arrayInitAdd(arrayChildState.data, arrayChildState.dataRule);
// 处理信息
const row: Record<string, any> = {};
for (const v of from.record) {
if (Array.isArray(v.array)) {
continue;
}
row[v.name] = Object.assign({}, v);
}
modalState.from = row;
modalState.type = 'arrayChildAdd';
modalState.title = `${arrayChildState.title} ${from.title}`;
modalState.key = from.key;
modalState.data = from.record.filter((v: any) => !Array.isArray(v.array));
modalState.open = true;
}
/**多列表新增单行确认 */
function arrayChildAddOk(from: Record<string, any>) {
const loc = `${arrayChildState.loc}/${from['index']['value']}`;
let data: Record<string, any> = {};
for (const key in from) {
// 子嵌套的不插入
if (from[key]['array']) {
continue;
}
// 检查规则
const [ok, msg] = ruleVerification(from[key]);
if (!ok) {
message.warning({
content: `${msg}`,
duration: 3,
});
return;
}
data[key] = from[key]['value'];
}
// 发送
const hide = message.loading(t('common.loading'), 0);
addPtNeConfigData({
neType: treeState.neType,
paramName: treeState.selectNode.paramName,
paramData: data,
loc,
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('views.configManage.configParamForm.addItemOk', {
num: modalState.title,
}),
duration: 3,
});
fnActiveConfigNode('#');
} else {
message.warning({
content: t('views.configManage.configParamForm.addItemErr'),
duration: 3,
});
}
})
.finally(() => {
hide();
arrayEditClose();
});
}
return {
arrayChildState,
arrayChildExpand,
arrayChildEdit,
arrayChildEditOk,
arrayChildDelete,
arrayChildAdd,
arrayChildAddOk,
};
}

View File

@@ -0,0 +1,139 @@
import { editPtNeConfigData } from '@/api/pt/neConfig';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { SizeType } from 'ant-design-vue/es/config-provider';
import message from 'ant-design-vue/es/message';
import { reactive, toRaw } from 'vue';
/**
* list类型参数处理
* @param param 父级传入 {t, treeState, ruleVerification}
* @returns
*/
export default function useConfigList({ t, treeState, ruleVerification }: any) {
/**单列表状态类型 */
type ListStateType = {
/**紧凑型 */
size: SizeType;
/**单列记录字段 */
columns: Record<string, any>[];
/**单列记录数据 */
data: Record<string, any>[];
/**编辑行记录 */
editRecord: Record<string, any>;
/**确认提交等待 */
confirmLoading: boolean;
};
/**单列表状态 */
let listState: ListStateType = reactive({
size: 'small',
columns: [
{
title: 'Key',
dataIndex: 'display',
align: 'left',
width: '30%',
},
{
title: 'Value',
dataIndex: 'value',
align: 'left',
width: '70%',
},
],
data: [],
confirmLoading: false,
editRecord: {},
});
/**单列表编辑 */
function listEdit(row: Record<string, any>) {
listState.editRecord = Object.assign({}, row);
}
/**单列表编辑关闭 */
function listEditClose() {
listState.confirmLoading = false;
listState.editRecord = {};
}
/**单列表编辑确认 */
function listEditOk() {
if (listState.confirmLoading) return;
const from = toRaw(listState.editRecord);
// 检查规则
const [ok, msg] = ruleVerification(from);
if (!ok) {
message.warning({
content: `${msg}`,
duration: 3,
});
return;
}
// 发送
listState.confirmLoading = true;
const hide = message.loading(t('common.loading'), 0);
editPtNeConfigData({
neType: treeState.neType,
paramName: treeState.selectNode.paramName,
paramData: {
[from['name']]: from['value'],
},
})
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success({
content: t('views.configManage.configParamForm.updateValue', {
num: from['display'],
}),
duration: 3,
});
// 改变表格数据
const item = listState.data.find(
(item: Record<string, any>) => from['name'] === item['name']
);
if (item) {
Object.assign(item, listState.editRecord);
}
} else {
message.warning({
content: t('views.configManage.configParamForm.updateValueErr'),
duration: 3,
});
}
})
.finally(() => {
hide();
listState.confirmLoading = false;
listState.editRecord = {};
});
}
/**表格分页器参数 */
let tablePagination = reactive({
/**当前页数 */
current: 1,
/**每页条数 */
pageSize: 10,
/**默认的每页条数 */
defaultPageSize: 10,
/**指定每页可以显示多少条 */
pageSizeOptions: ['10', '20', '50', '100'],
/**只有一页时是否隐藏分页器 */
hideOnSinglePage: true,
/**是否可以快速跳转至某页 */
showQuickJumper: true,
/**是否可以改变 pageSize */
showSizeChanger: true,
/**数据总数 */
total: 0,
showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
onChange: (page: number, pageSize: number) => {
tablePagination.current = page;
tablePagination.pageSize = pageSize;
},
});
return { tablePagination, listState, listEdit, listEditClose, listEditOk };
}

View File

@@ -0,0 +1,192 @@
import { getNeConfigData } from '@/api/ne/neConfig';
import { regExpIPv4, regExpIPv6, validURL } from '@/utils/regular-utils';
import { ref } from 'vue';
/**
* 参数公共函数
* @param param 父级传入 {t}
* @returns
*/
export default function useOptions({ t }: any) {
/**规则校验 */
function ruleVerification(row: Record<string, any>): (string | boolean)[] {
let result = [true, ''];
const type = row.type;
const value = row.value;
const filter = row.filter;
const display = row.display;
// 子嵌套的不检查
if (row.array) {
return result;
}
// 可选的同时没有值不检查
if (row.optional === 'true' && !value) {
return result;
}
switch (type) {
case 'int':
// filter: "0~128"
if (filter && filter.indexOf('~') !== -1) {
const filterArr = filter.split('~');
const minInt = parseInt(filterArr[0]);
const maxInt = parseInt(filterArr[1]);
const valueInt = parseInt(value);
if (valueInt < minInt || valueInt > maxInt) {
return [
false,
t('views.configManage.configParamForm.requireInt', {
display,
filter,
}),
];
}
}
break;
case 'ipv4':
if (!regExpIPv4.test(value)) {
return [
false,
t('views.configManage.configParamForm.requireIpv4', { display }),
];
}
break;
case 'ipv6':
if (!regExpIPv6.test(value)) {
return [
false,
t('views.configManage.configParamForm.requireIpv6', { display }),
];
}
break;
case 'enum':
if (filter && filter.indexOf('{') === 1) {
let filterJson: Record<string, any> = {};
try {
filterJson = JSON.parse(filter); //string---json
} catch (error) {
console.error(error);
}
if (!Object.keys(filterJson).includes(`${value}`)) {
return [
false,
t('views.configManage.configParamForm.requireEnum', { display }),
];
}
}
break;
case 'bool':
// filter: '{"0":"false", "1":"true"}'
if (filter && filter.indexOf('{') === 1) {
let filterJson: Record<string, any> = {};
try {
filterJson = JSON.parse(filter); //string---json
} catch (error) {
console.error(error);
}
if (!Object.values(filterJson).includes(`${value}`)) {
return [
false,
t('views.configManage.configParamForm.requireBool', { display }),
];
}
}
break;
case 'string':
// filter: "0~128"
// 字符串长度判断
if (filter && filter.indexOf('~') !== -1) {
try {
const filterArr = filter.split('~');
let rule = new RegExp(
'^\\S{' + filterArr[0] + ',' + filterArr[1] + '}$'
);
if (!rule.test(value)) {
return [
false,
t('views.configManage.configParamForm.requireString', {
display,
}),
];
}
} catch (error) {
console.error(error);
}
}
// 字符串http判断
if (value.startsWith('http')) {
try {
if (!validURL(value)) {
return [
false,
t('views.configManage.configParamForm.requireString', {
display,
}),
];
}
} catch (error) {
console.error(error);
}
}
break;
case 'regex':
// filter: "^[0-9]{3}$"
if (filter) {
try {
let regex = new RegExp(filter);
if (!regex.test(value)) {
return [
false,
t('views.configManage.configParamForm.requireString', {
display,
}),
];
}
} catch (error) {
console.error(error);
}
}
break;
default:
return [
false,
t('views.configManage.configParamForm.requireUn', { display }),
];
}
return result;
}
/**upfId可选择 */
const SMFByUPFIdOptions = ref<{ value: string; label: string }[]>([]);
/**加载smf配置的upfId */
function getConfigSMFByUPFIds(neId: string) {
getNeConfigData({
neType: 'SMF',
neId: neId,
paramName: 'upfConfig',
}).then(res => {
SMFByUPFIdOptions.value = [];
for (const s of res.data) {
SMFByUPFIdOptions.value.push({
value: s.id,
label: s.id,
});
}
});
}
return {
ruleVerification,
getConfigSMFByUPFIds,
SMFByUPFIdOptions,
};
}

View File

@@ -0,0 +1,228 @@
import { ptSaveAsDefault, ptResetAsDefault } from '@/api/pt/neConfig';
import {
getPtClassStudents,
stuPtNeConfigApply,
updatePtNeConfigApply,
} from '@/api/pt/neConfigApply';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { hasRoles } from '@/plugins/auth-user';
import { message } from 'ant-design-vue/lib';
import { computed, onMounted, reactive } from 'vue';
/**
* 实训教学函数
* @param param 父级传入 {t,fnActiveConfigNode}
* @returns
*/
export default function usePtOptions({ t, fnActiveConfigNode }: any) {
const ptConfigState = reactive({
saveLoading: false,
restLoading: false,
applyLoading: false,
});
/**(管理员)保存网元下所有配置为示例配置 */
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,
});
} 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,
});
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
}
})
.finally(() => {
ptConfigState.restLoading = false;
fnActiveConfigNode('#');
});
}
/**配置下方应用(学生)申请撤回和(管理/教师)应用退回 */
function ptConfigApply(
neType: string,
status: '0' | '1' | '2' | '3',
student?: string
) {
let result: any;
if (status === '2' || status === '3') {
let from: {
neType: string;
status: string;
student?: string;
backInfo?: string;
} = {
neType,
status: '2',
};
if (student) {
if (status === '2') {
from = { neType, status, student };
}
if (status === '3') {
from = { neType, status, student, backInfo: '请重新检查配置' };
}
}
result = updatePtNeConfigApply(from);
}
if (status === '0' || status === '1') {
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;
}
}
} else {
message.error({
content: `${res.msg}`,
duration: 3,
});
}
})
.finally(() => {
ptConfigState.applyLoading = false;
});
}
const classState = reactive<{
/**学生账号 */
student: string | undefined;
/**学生可选择列表 */
studentOptions: {
value: string;
label: string;
applyId: string;
applyStatus: string;
}[];
studentOptionsDef: {
value: string;
label: string;
applyId: string;
applyStatus: string;
}[];
}>({
student: undefined,
studentOptions: [],
studentOptionsDef: [],
});
// 仅教师加载
if (hasRoles(['teacher'])) {
onMounted(() => {
classStudents(); // 初始学生列表
});
}
/**学生选择搜索 */
function studentChange(v: any) {
if (!v) {
Object.assign(classState.studentOptions, classState.studentOptionsDef);
}
fnActiveConfigNode('#');
}
let timeout: any;
/**学生选择搜索 */
function studentSearch(val: string) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
if (!val) {
Object.assign(classState.studentOptions, classState.studentOptionsDef);
return;
}
timeout = setTimeout(() => classStudents(val), 500);
}
/**班级学生列表 */
function classStudents(val?: string) {
getPtClassStudents({ userName: val }).then(res => {
classState.studentOptions = [];
if (!Array.isArray(res.data) || res.data.length <= 0) {
return;
}
for (const v of res.data) {
classState.studentOptions.push({
value: v.userName,
label: v.userName,
applyId: v.applyId,
applyStatus: v.applyStatus,
});
// 设为最新状态
const item = classState.studentOptionsDef.find(
s => s.value === v.userName
);
if (item) {
item.applyStatus = v.applyStatus;
}
}
if (!val) {
Object.assign(classState.studentOptionsDef, classState.studentOptions);
}
});
}
// 学生状态
const studentStatus = computed(() => {
const item = classState.studentOptionsDef.find(
s => s.value === classState.student
);
if (item) return item.applyStatus;
return '';
});
return {
ptConfigState,
ptConfigSave,
ptConfigReset,
ptConfigApply,
classState,
studentStatus,
studentSearch,
studentChange,
};
}