mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-24 04:16:38 +08:00
296 lines
7.5 KiB
TypeScript
296 lines
7.5 KiB
TypeScript
export type ListItem = {
|
||
id?: number;
|
||
children?: ListItem[];
|
||
[key: string]: any;
|
||
};
|
||
export type BaseMockOptions = { name: string; copyTimes?: number; list: ListItem[]; idGenerator: number };
|
||
type CopyListParams = { originList: ListItem[]; newList: ListItem[]; options: BaseMockOptions; parentId?: number };
|
||
|
||
function copyList(props: CopyListParams) {
|
||
const { originList, newList, options, parentId } = props;
|
||
for (const item of originList) {
|
||
const newItem: ListItem = { ...item, parentId };
|
||
newItem.id = options.idGenerator;
|
||
options.idGenerator += 1;
|
||
newList.push(newItem);
|
||
if (item.children) {
|
||
newItem.children = [];
|
||
copyList({
|
||
originList: item.children,
|
||
newList: newItem.children,
|
||
options,
|
||
parentId: newItem.id
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
function delById(req: Service.MockOption, list: any[]) {
|
||
for (let i = 0; i < list.length; i += 1) {
|
||
const item = list[i];
|
||
if (item.id === parseInt(req.query.id, 10)) {
|
||
list.splice(i, 1);
|
||
break;
|
||
}
|
||
if (item.children && item.children.length > 0) {
|
||
delById(req, item.children);
|
||
}
|
||
}
|
||
}
|
||
|
||
function findById(id: number, list: ListItem[]): any {
|
||
for (const item of list) {
|
||
if (item.id === id) {
|
||
return item;
|
||
}
|
||
if (item.children && item.children.length > 0) {
|
||
const sub = findById(id, item.children);
|
||
if (sub !== null && sub !== undefined) {
|
||
return sub;
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
function matchWithArrayCondition(value: any[], item: ListItem, key: string) {
|
||
if (value.length === 0) {
|
||
return true;
|
||
}
|
||
let matched = false;
|
||
for (const i of value) {
|
||
if (item[key] instanceof Array) {
|
||
for (const j of item[key]) {
|
||
if (i === j) {
|
||
matched = true;
|
||
break;
|
||
}
|
||
}
|
||
if (matched) {
|
||
break;
|
||
}
|
||
} else if (item[key] === i || (typeof item[key] === 'string' && item[key].indexOf(`${i}`) >= 0)) {
|
||
matched = true;
|
||
break;
|
||
}
|
||
if (matched) {
|
||
break;
|
||
}
|
||
}
|
||
return matched;
|
||
}
|
||
|
||
function matchWithObjectCondition(value: any, item: ListItem, key: string) {
|
||
let matched = true;
|
||
for (const key2 of Object.keys(value)) {
|
||
const v = value[key2];
|
||
if (v && item[key] && v !== item[key][key2]) {
|
||
matched = false;
|
||
break;
|
||
}
|
||
}
|
||
return matched;
|
||
}
|
||
|
||
function searchFromList(list: ListItem[], query: any) {
|
||
const filter = (item: ListItem) => {
|
||
let allFound = true; // 是否所有条件都符合
|
||
for (const key of Object.keys(query)) {
|
||
const value = query[key];
|
||
if (value === undefined || value === null || value === '') {
|
||
// no nothing
|
||
} else if (value instanceof Array) {
|
||
// 如果条件中的value是数组的话,只要查到一个就行
|
||
const matched = matchWithArrayCondition(value, item, key);
|
||
if (!matched) {
|
||
allFound = false;
|
||
}
|
||
} else if (value instanceof Object) {
|
||
// 如果条件中的value是对象的话,需要每个key都匹配
|
||
const matched = matchWithObjectCondition(value, item, key);
|
||
if (!matched) {
|
||
allFound = false;
|
||
}
|
||
} else if (item[key] !== value) {
|
||
allFound = false;
|
||
}
|
||
}
|
||
return allFound;
|
||
};
|
||
return list.filter(filter);
|
||
}
|
||
|
||
export default {
|
||
buildMock(options: BaseMockOptions) {
|
||
const name = options.name;
|
||
if (!options.copyTimes) {
|
||
options.copyTimes = 29;
|
||
}
|
||
const list: any[] = [];
|
||
for (let i = 0; i < options.copyTimes; i += 1) {
|
||
copyList({
|
||
originList: options.list,
|
||
newList: list,
|
||
options
|
||
});
|
||
}
|
||
options.list = list;
|
||
return [
|
||
{
|
||
path: `/mock/${name}/page`,
|
||
method: 'post',
|
||
handle(req: Service.MockOption) {
|
||
let data = [...list];
|
||
let limit = 20;
|
||
let offset = 0;
|
||
for (const item of list) {
|
||
if (item.children && item.children.length === 0) {
|
||
item.hasChildren = false;
|
||
item.lazy = false;
|
||
}
|
||
}
|
||
let orderAsc: any;
|
||
let orderProp: any;
|
||
if (req && req.body) {
|
||
const { page, query } = req.body;
|
||
if (page.limit) {
|
||
limit = parseInt(page.limit, 10);
|
||
}
|
||
if (page.offset) {
|
||
offset = parseInt(page.offset, 10);
|
||
}
|
||
if (Object.keys(query).length > 0) {
|
||
data = searchFromList(list, query);
|
||
}
|
||
}
|
||
|
||
const start = offset;
|
||
let end = offset + limit;
|
||
if (data.length < end) {
|
||
end = data.length;
|
||
}
|
||
|
||
if (orderProp) {
|
||
// 排序
|
||
data.sort((a, b) => {
|
||
let ret = 0;
|
||
if (a[orderProp] > b[orderProp]) {
|
||
ret = 1;
|
||
} else if (a[orderProp] < b[orderProp]) {
|
||
ret = -1;
|
||
}
|
||
return orderAsc ? ret : -ret;
|
||
});
|
||
}
|
||
|
||
const records = data.slice(start, end);
|
||
const lastOffset = data.length - (data.length % limit);
|
||
if (offset > lastOffset) {
|
||
offset = lastOffset;
|
||
}
|
||
return {
|
||
code: 200,
|
||
message: 'success',
|
||
data: {
|
||
records,
|
||
total: data.length,
|
||
limit,
|
||
offset
|
||
}
|
||
};
|
||
}
|
||
},
|
||
{
|
||
path: `/mock/${name}/get`,
|
||
method: 'get',
|
||
handle(req: Service.MockOption) {
|
||
let id = req.query.id;
|
||
id = parseInt(id, 10);
|
||
let current = null;
|
||
for (const item of list) {
|
||
if (item.id === id) {
|
||
current = item;
|
||
break;
|
||
}
|
||
}
|
||
return {
|
||
code: 200,
|
||
message: 'success',
|
||
data: current
|
||
};
|
||
}
|
||
},
|
||
{
|
||
path: `/mock/${name}/add`,
|
||
method: 'post',
|
||
handle(req: Service.MockOption) {
|
||
req.body.id = options.idGenerator;
|
||
options.idGenerator += 1;
|
||
list.unshift(req.body);
|
||
return {
|
||
code: 200,
|
||
message: 'success',
|
||
data: req.body.id
|
||
};
|
||
}
|
||
},
|
||
{
|
||
path: `/mock/${name}/update`,
|
||
method: 'post',
|
||
handle(req: Service.MockOption) {
|
||
const item = findById(req.body.id, list);
|
||
if (item) {
|
||
Object.assign(item, req.body);
|
||
}
|
||
return {
|
||
code: 200,
|
||
message: 'success',
|
||
data: null
|
||
};
|
||
}
|
||
},
|
||
{
|
||
path: `/mock/${name}/delete`,
|
||
method: 'post',
|
||
handle(req: Service.MockOption) {
|
||
delById(req, list);
|
||
return {
|
||
code: 200,
|
||
message: 'success',
|
||
data: null
|
||
};
|
||
}
|
||
},
|
||
{
|
||
path: `/mock/${name}/batchDelete`,
|
||
method: 'post',
|
||
handle(req: Service.MockOption) {
|
||
const ids = req.body.ids;
|
||
for (let i = list.length - 1; i >= 0; i -= 1) {
|
||
const item = list[i];
|
||
if (ids.indexOf(item.id) >= 0) {
|
||
list.splice(i, 1);
|
||
}
|
||
}
|
||
return {
|
||
code: 200,
|
||
message: 'success',
|
||
data: null
|
||
};
|
||
}
|
||
},
|
||
{
|
||
path: `/mock/${name}/all`,
|
||
method: 'post',
|
||
handle() {
|
||
return {
|
||
code: 200,
|
||
message: 'success',
|
||
data: list
|
||
};
|
||
}
|
||
}
|
||
];
|
||
}
|
||
};
|