feat: 实训教学模块
This commit is contained in:
@@ -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,
|
||||
};
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
@@ -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 };
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user