项目初始化
This commit is contained in:
1
_mock/README.md
Normal file
1
_mock/README.md
Normal file
@ -0,0 +1 @@
|
||||
[Document](https://ng-alain.com/mock)
|
||||
265
_mock/_api.ts
Normal file
265
_mock/_api.ts
Normal file
@ -0,0 +1,265 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
|
||||
// region: mock data
|
||||
|
||||
const titles = ['Alipay', 'Angular', 'Ant Design', 'Ant Design Pro', 'Bootstrap', 'React', 'Vue', 'Webpack'];
|
||||
|
||||
const avatars = [
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', // Alipay
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', // Angular
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', // Ant Design
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', // Ant Design Pro
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', // Bootstrap
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png', // React
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', // Vue
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png', // Webpack
|
||||
];
|
||||
const covers = [
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/HrxcVbrKnCJOZvtzSqjN.png',
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/alaPpKWajEbIYEUvvVNf.png',
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/RLwlKSYGSXGHuWSojyvp.png',
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png',
|
||||
];
|
||||
const desc = [
|
||||
'那是一种内在的东西, 他们到达不了,也无法触及的',
|
||||
'希望是一个好东西,也许是最好的,好东西是不会消亡的',
|
||||
'生命就像一盒巧克力,结果往往出人意料',
|
||||
'城镇中有那么多的酒馆,她却偏偏走进了我的酒馆',
|
||||
'那时候我只会想自己想要什么,从不想自己拥有什么',
|
||||
];
|
||||
|
||||
const user = ['卡色', 'cipchk', '付小小', '曲丽丽', '林东东', '周星星', '吴加好', '朱偏右', '鱼酱', '乐哥', '谭小仪', '仲尼'];
|
||||
|
||||
// endregion
|
||||
|
||||
function getFakeList(count: number = 20): any[] {
|
||||
const list: any[] = [];
|
||||
for (let i = 0; i < count; i += 1) {
|
||||
list.push({
|
||||
id: `fake-list-${i}`,
|
||||
owner: user[i % 10],
|
||||
title: titles[i % 8],
|
||||
avatar: avatars[i % 8],
|
||||
cover: parseInt((i / 4).toString(), 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)],
|
||||
status: ['active', 'exception', 'normal'][i % 3],
|
||||
percent: Math.ceil(Math.random() * 50) + 50,
|
||||
logo: avatars[i % 8],
|
||||
href: 'https://ant.design',
|
||||
updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i),
|
||||
createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i),
|
||||
subDescription: desc[i % 5],
|
||||
description:
|
||||
'在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。',
|
||||
activeUser: Math.ceil(Math.random() * 100000) + 100000,
|
||||
newUser: Math.ceil(Math.random() * 1000) + 1000,
|
||||
star: Math.ceil(Math.random() * 100) + 100,
|
||||
like: Math.ceil(Math.random() * 100) + 100,
|
||||
message: Math.ceil(Math.random() * 10) + 10,
|
||||
content:
|
||||
'段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。',
|
||||
members: [
|
||||
{
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png',
|
||||
name: '曲丽丽',
|
||||
},
|
||||
{
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png',
|
||||
name: '王昭君',
|
||||
},
|
||||
{
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png',
|
||||
name: '董娜娜',
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
function getNotice(): any[] {
|
||||
return [
|
||||
{
|
||||
id: 'xxx1',
|
||||
title: titles[0],
|
||||
logo: avatars[0],
|
||||
description: '那是一种内在的东西, 他们到达不了,也无法触及的',
|
||||
updatedAt: new Date(),
|
||||
member: '科学搬砖组',
|
||||
href: '',
|
||||
memberLink: '',
|
||||
},
|
||||
{
|
||||
id: 'xxx2',
|
||||
title: titles[1],
|
||||
logo: avatars[1],
|
||||
description: '希望是一个好东西,也许是最好的,好东西是不会消亡的',
|
||||
updatedAt: new Date('2017-07-24'),
|
||||
member: '全组都是吴彦祖',
|
||||
href: '',
|
||||
memberLink: '',
|
||||
},
|
||||
{
|
||||
id: 'xxx3',
|
||||
title: titles[2],
|
||||
logo: avatars[2],
|
||||
description: '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆',
|
||||
updatedAt: new Date(),
|
||||
member: '中二少女团',
|
||||
href: '',
|
||||
memberLink: '',
|
||||
},
|
||||
{
|
||||
id: 'xxx4',
|
||||
title: titles[3],
|
||||
logo: avatars[3],
|
||||
description: '那时候我只会想自己想要什么,从不想自己拥有什么',
|
||||
updatedAt: new Date('2017-07-23'),
|
||||
member: '程序员日常',
|
||||
href: '',
|
||||
memberLink: '',
|
||||
},
|
||||
{
|
||||
id: 'xxx5',
|
||||
title: titles[4],
|
||||
logo: avatars[4],
|
||||
description: '凛冬将至',
|
||||
updatedAt: new Date('2017-07-23'),
|
||||
member: '高逼格设计天团',
|
||||
href: '',
|
||||
memberLink: '',
|
||||
},
|
||||
{
|
||||
id: 'xxx6',
|
||||
title: titles[5],
|
||||
logo: avatars[5],
|
||||
description: '生命就像一盒巧克力,结果往往出人意料',
|
||||
updatedAt: new Date('2017-07-23'),
|
||||
member: '骗你来学计算机',
|
||||
href: '',
|
||||
memberLink: '',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function getActivities(): any[] {
|
||||
return [
|
||||
{
|
||||
id: 'trend-1',
|
||||
updatedAt: new Date(),
|
||||
user: {
|
||||
name: '林东东',
|
||||
avatar: avatars[0],
|
||||
},
|
||||
group: {
|
||||
name: '高逼格设计天团',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
project: {
|
||||
name: '六月迭代',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
template: '在 @{group} 新建项目 @{project}',
|
||||
},
|
||||
{
|
||||
id: 'trend-2',
|
||||
updatedAt: new Date(),
|
||||
user: {
|
||||
name: '付小小',
|
||||
avatar: avatars[1],
|
||||
},
|
||||
group: {
|
||||
name: '高逼格设计天团',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
project: {
|
||||
name: '六月迭代',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
template: '在 @{group} 新建项目 @{project}',
|
||||
},
|
||||
{
|
||||
id: 'trend-3',
|
||||
updatedAt: new Date(),
|
||||
user: {
|
||||
name: '曲丽丽',
|
||||
avatar: avatars[2],
|
||||
},
|
||||
group: {
|
||||
name: '中二少女团',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
project: {
|
||||
name: '六月迭代',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
template: '在 @{group} 新建项目 @{project}',
|
||||
},
|
||||
{
|
||||
id: 'trend-4',
|
||||
updatedAt: new Date(),
|
||||
user: {
|
||||
name: '周星星',
|
||||
avatar: avatars[3],
|
||||
},
|
||||
project: {
|
||||
name: '5 月日常迭代',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
template: '将 @{project} 更新至已发布状态',
|
||||
},
|
||||
{
|
||||
id: 'trend-5',
|
||||
updatedAt: new Date(),
|
||||
user: {
|
||||
name: '朱偏右',
|
||||
avatar: avatars[4],
|
||||
},
|
||||
project: {
|
||||
name: '工程效能',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
comment: {
|
||||
name: '留言',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
template: '在 @{project} 发布了 @{comment}',
|
||||
},
|
||||
{
|
||||
id: 'trend-6',
|
||||
updatedAt: new Date(),
|
||||
user: {
|
||||
name: '乐哥',
|
||||
avatar: avatars[5],
|
||||
},
|
||||
group: {
|
||||
name: '程序员日常',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
project: {
|
||||
name: '品牌迭代',
|
||||
link: 'http://github.com/',
|
||||
},
|
||||
template: '在 @{group} 新建项目 @{project}',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export const APIS = {
|
||||
'/api/list': (req: MockRequest) => getFakeList(req.queryString.count),
|
||||
'/api/notice': () => getNotice(),
|
||||
'/api/activities': () => getActivities(),
|
||||
'POST /api/auth/refresh': { msg: 'ok', token: 'new-token-by-refresh' },
|
||||
'/api/401': () => {
|
||||
throw new MockStatusError(401);
|
||||
},
|
||||
'/api/403': () => {
|
||||
throw new MockStatusError(403);
|
||||
},
|
||||
'/api/404': () => {
|
||||
throw new MockStatusError(404);
|
||||
},
|
||||
'/api/500': () => {
|
||||
throw new MockStatusError(500);
|
||||
},
|
||||
};
|
||||
205
_mock/_chart.ts
Normal file
205
_mock/_chart.ts
Normal file
@ -0,0 +1,205 @@
|
||||
import { format } from 'date-fns';
|
||||
import * as Mock from 'mockjs';
|
||||
|
||||
// region: mock data
|
||||
|
||||
const visitData: any[] = [];
|
||||
const beginDay = new Date().getTime();
|
||||
|
||||
const fakeY = [7, 5, 4, 2, 4, 7, 5, 6, 5, 9, 6, 3, 1, 5, 3, 6, 5];
|
||||
for (let i = 0; i < fakeY.length; i += 1) {
|
||||
visitData.push({
|
||||
x: format(new Date(beginDay + 1000 * 60 * 60 * 24 * i), 'yyyy-MM-dd'),
|
||||
y: fakeY[i],
|
||||
});
|
||||
}
|
||||
|
||||
const visitData2: any[] = [];
|
||||
const fakeY2 = [1, 6, 4, 8, 3, 7, 2];
|
||||
for (let i = 0; i < fakeY2.length; i += 1) {
|
||||
visitData2.push({
|
||||
x: format(new Date(beginDay + 1000 * 60 * 60 * 24 * i), 'yyyy-MM-dd'),
|
||||
y: fakeY2[i],
|
||||
});
|
||||
}
|
||||
|
||||
const salesData: any[] = [];
|
||||
for (let i = 0; i < 12; i += 1) {
|
||||
salesData.push({
|
||||
x: `${i + 1}月`,
|
||||
y: Math.floor(Math.random() * 1000) + 200,
|
||||
});
|
||||
}
|
||||
const searchData: any[] = [];
|
||||
for (let i = 0; i < 50; i += 1) {
|
||||
searchData.push({
|
||||
index: i + 1,
|
||||
keyword: `搜索关键词-${i}`,
|
||||
count: Math.floor(Math.random() * 1000),
|
||||
range: Math.floor(Math.random() * 100),
|
||||
status: Math.floor((Math.random() * 10) % 2),
|
||||
});
|
||||
}
|
||||
const salesTypeData = [
|
||||
{
|
||||
x: '家用电器',
|
||||
y: 4544,
|
||||
},
|
||||
{
|
||||
x: '食用酒水',
|
||||
y: 3321,
|
||||
},
|
||||
{
|
||||
x: '个护健康',
|
||||
y: 3113,
|
||||
},
|
||||
{
|
||||
x: '服饰箱包',
|
||||
y: 2341,
|
||||
},
|
||||
{
|
||||
x: '母婴产品',
|
||||
y: 1231,
|
||||
},
|
||||
{
|
||||
x: '其他',
|
||||
y: 1231,
|
||||
},
|
||||
];
|
||||
|
||||
const salesTypeDataOnline = [
|
||||
{
|
||||
x: '家用电器',
|
||||
y: 244,
|
||||
},
|
||||
{
|
||||
x: '食用酒水',
|
||||
y: 321,
|
||||
},
|
||||
{
|
||||
x: '个护健康',
|
||||
y: 311,
|
||||
},
|
||||
{
|
||||
x: '服饰箱包',
|
||||
y: 41,
|
||||
},
|
||||
{
|
||||
x: '母婴产品',
|
||||
y: 121,
|
||||
},
|
||||
{
|
||||
x: '其他',
|
||||
y: 111,
|
||||
},
|
||||
];
|
||||
|
||||
const salesTypeDataOffline = [
|
||||
{
|
||||
x: '家用电器',
|
||||
y: 99,
|
||||
},
|
||||
{
|
||||
x: '个护健康',
|
||||
y: 188,
|
||||
},
|
||||
{
|
||||
x: '服饰箱包',
|
||||
y: 344,
|
||||
},
|
||||
{
|
||||
x: '母婴产品',
|
||||
y: 255,
|
||||
},
|
||||
{
|
||||
x: '其他',
|
||||
y: 65,
|
||||
},
|
||||
];
|
||||
|
||||
const offlineData: any[] = [];
|
||||
for (let i = 0; i < 10; i += 1) {
|
||||
offlineData.push({
|
||||
name: `门店${i}`,
|
||||
cvr: Math.ceil(Math.random() * 9) / 10,
|
||||
});
|
||||
}
|
||||
const offlineChartData: any[] = [];
|
||||
for (let i = 0; i < 20; i += 1) {
|
||||
offlineChartData.push({
|
||||
time: new Date().getTime() + 1000 * 60 * 30 * i,
|
||||
y1: Math.floor(Math.random() * 100) + 10,
|
||||
y2: Math.floor(Math.random() * 100) + 10,
|
||||
});
|
||||
}
|
||||
|
||||
const radarOriginData = [
|
||||
{
|
||||
name: '个人',
|
||||
ref: 10,
|
||||
koubei: 8,
|
||||
output: 4,
|
||||
contribute: 5,
|
||||
hot: 7,
|
||||
},
|
||||
{
|
||||
name: '团队',
|
||||
ref: 3,
|
||||
koubei: 9,
|
||||
output: 6,
|
||||
contribute: 3,
|
||||
hot: 1,
|
||||
},
|
||||
{
|
||||
name: '部门',
|
||||
ref: 4,
|
||||
koubei: 1,
|
||||
output: 6,
|
||||
contribute: 5,
|
||||
hot: 7,
|
||||
},
|
||||
];
|
||||
|
||||
//
|
||||
const radarData: any[] = [];
|
||||
const radarTitleMap: any = {
|
||||
ref: '引用',
|
||||
koubei: '口碑',
|
||||
output: '产量',
|
||||
contribute: '贡献',
|
||||
hot: '热度',
|
||||
};
|
||||
radarOriginData.forEach((item: any) => {
|
||||
Object.keys(item).forEach((key) => {
|
||||
if (key !== 'name') {
|
||||
radarData.push({
|
||||
name: item.name,
|
||||
label: radarTitleMap[key],
|
||||
value: item[key],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// endregion
|
||||
|
||||
export const CHARTS = {
|
||||
'/chart': JSON.parse(
|
||||
JSON.stringify({
|
||||
visitData,
|
||||
visitData2,
|
||||
salesData,
|
||||
searchData,
|
||||
offlineData,
|
||||
offlineChartData,
|
||||
salesTypeData,
|
||||
salesTypeDataOnline,
|
||||
salesTypeDataOffline,
|
||||
radarData,
|
||||
}),
|
||||
),
|
||||
'/chart/visit': JSON.parse(JSON.stringify(visitData)),
|
||||
'/chart/tags': Mock.mock({
|
||||
'list|100': [{ name: '@city', 'value|1-100': 150 }],
|
||||
}),
|
||||
};
|
||||
126
_mock/_file-manager.ts
Normal file
126
_mock/_file-manager.ts
Normal file
@ -0,0 +1,126 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { deepCopy } from '@delon/util';
|
||||
import { Random } from 'mockjs';
|
||||
|
||||
import { genMp } from './utils';
|
||||
|
||||
interface FileItem {
|
||||
id?: number;
|
||||
parent_id?: number;
|
||||
type?: 'folder' | 'file';
|
||||
title?: string;
|
||||
mp?: string;
|
||||
ext?: string;
|
||||
size?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
created?: Date;
|
||||
}
|
||||
|
||||
let point = 1;
|
||||
let DATA: FileItem[] = [];
|
||||
DATA = DATA.concat(...genFolds(0, 3), ...genFiles(1, 6), ...genFiles(2, 3), ...genFiles(0, 1, 'zip'), ...genFiles(0, 10));
|
||||
|
||||
function genFolds(parent_id: number, count: number): FileItem[] {
|
||||
return new Array(count).fill({}).map(() => {
|
||||
return {
|
||||
id: point++,
|
||||
parent_id,
|
||||
type: 'folder',
|
||||
ext: 'folder',
|
||||
title: Random.ctitle(3, 5),
|
||||
created: new Date()
|
||||
} as FileItem;
|
||||
});
|
||||
}
|
||||
|
||||
function genFiles(parent_id: number, count: number, ext: string = 'png'): FileItem[] {
|
||||
return new Array(count).fill({}).map(() => {
|
||||
return {
|
||||
id: point++,
|
||||
parent_id,
|
||||
type: 'file',
|
||||
title: `${Random.ctitle(3, 5)}.${ext}`,
|
||||
mp: genMp(),
|
||||
is_img: ext === 'png',
|
||||
ext,
|
||||
size: Random.natural(10, 10000),
|
||||
width: Random.natural(100, 1000),
|
||||
height: Random.natural(100, 1000),
|
||||
created: new Date()
|
||||
} as FileItem;
|
||||
});
|
||||
}
|
||||
|
||||
function get(params: any): any {
|
||||
let ret = deepCopy(DATA) as FileItem[];
|
||||
const parent_id = +(params.parent_id || '0');
|
||||
ret = ret.filter(data => data.parent_id === parent_id);
|
||||
if (params.type) {
|
||||
ret = ret.filter(data => data.type!.indexOf(params.type) > -1);
|
||||
}
|
||||
if (params.q) {
|
||||
ret = ret.filter(data => data.title!.indexOf(params.q) > -1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getIdx(id: number): number {
|
||||
id = +id;
|
||||
const idx = DATA.findIndex(w => w.id === id);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
export const FILES = {
|
||||
'/file/folder': () => deepCopy(DATA).filter((w: any) => w.type === 'folder'),
|
||||
'/file': (req: MockRequest) => {
|
||||
const pi = +(req.queryString.pi || 1);
|
||||
const ps = +(req.queryString.ps || 10);
|
||||
const data = get(req.queryString);
|
||||
return {
|
||||
total: data.length,
|
||||
list: data.slice((pi - 1) * ps, pi * ps)
|
||||
};
|
||||
},
|
||||
'POST /file': (req: MockRequest) => {
|
||||
const file = req.body.get('file') as File;
|
||||
const parent_id = +req.body.get('parent_id');
|
||||
const item = Object.assign(genFiles(req.body.parent_id, 1)[0], {
|
||||
parent_id,
|
||||
title: file.name,
|
||||
size: file.size
|
||||
});
|
||||
DATA.push(item);
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'/file/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
const item = { ...DATA[idx], ...req.body };
|
||||
return item;
|
||||
},
|
||||
'POST /file/rename': (req: MockRequest) => {
|
||||
const idx = getIdx(req.body.id || 0);
|
||||
DATA[idx].title = req.body.title;
|
||||
return { msg: 'ok', item: DATA[idx] };
|
||||
},
|
||||
'POST /file/move': (req: MockRequest) => {
|
||||
const idx = getIdx(req.body.id || 0);
|
||||
DATA[idx].parent_id = req.body.moveId;
|
||||
return { msg: 'ok', item: DATA[idx] };
|
||||
},
|
||||
'POST /file/copy/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
const item = { ...DATA[idx], id: point++ };
|
||||
item.title += ' - Copy';
|
||||
DATA.push(item);
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'DELETE /file/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
DATA.splice(idx, 1);
|
||||
return { msg: 'ok' };
|
||||
}
|
||||
};
|
||||
258
_mock/_forum.ts
Normal file
258
_mock/_forum.ts
Normal file
@ -0,0 +1,258 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { deepCopy } from '@delon/util';
|
||||
import { Random } from 'mockjs';
|
||||
import { genLabel, genMp } from './utils';
|
||||
|
||||
let id = 1;
|
||||
const CATEGORY = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'General',
|
||||
list: [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Getting started',
|
||||
threads: Random.natural(1, 20),
|
||||
replies: Random.natural(6, 100),
|
||||
last: {
|
||||
id: id++,
|
||||
mp: genMp(),
|
||||
title: Random.title(5, 10),
|
||||
user_name: Random.name(),
|
||||
time: '1d ago',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Announcements',
|
||||
threads: Random.natural(1, 20),
|
||||
replies: Random.natural(6, 100),
|
||||
last: {
|
||||
id: id++,
|
||||
mp: genMp(),
|
||||
title: Random.title(5, 10),
|
||||
user_name: Random.name(),
|
||||
time: '1d ago',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Guides',
|
||||
threads: Random.natural(1, 20),
|
||||
replies: Random.natural(6, 100),
|
||||
last: {
|
||||
id: id++,
|
||||
mp: genMp(),
|
||||
title: Random.title(5, 10),
|
||||
user_name: Random.name(),
|
||||
time: '1d ago',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Shopping',
|
||||
list: [
|
||||
{
|
||||
id: 4,
|
||||
title: 'Guides',
|
||||
threads: Random.natural(1, 20),
|
||||
replies: Random.natural(6, 100),
|
||||
last: {
|
||||
id: id++,
|
||||
mp: genMp(),
|
||||
title: Random.title(5, 10),
|
||||
user_name: Random.name(),
|
||||
time: '1d ago',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: 'Payments',
|
||||
threads: Random.natural(1, 20),
|
||||
replies: Random.natural(6, 100),
|
||||
last: {
|
||||
id: id++,
|
||||
mp: genMp(),
|
||||
title: Random.title(5, 10),
|
||||
user_name: Random.name(),
|
||||
time: '1d ago',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: 'Products',
|
||||
threads: Random.natural(1, 20),
|
||||
replies: Random.natural(6, 100),
|
||||
last: {
|
||||
id: id++,
|
||||
mp: genMp(),
|
||||
title: Random.title(5, 10),
|
||||
user_name: Random.name(),
|
||||
time: '1d ago',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
title: 'Refund',
|
||||
threads: Random.natural(1, 20),
|
||||
replies: Random.natural(6, 100),
|
||||
last: {
|
||||
id: id++,
|
||||
mp: genMp(),
|
||||
title: Random.title(5, 10),
|
||||
user_name: Random.name(),
|
||||
time: '1d ago',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Support',
|
||||
list: [
|
||||
{
|
||||
id: 8,
|
||||
title: 'Common questions',
|
||||
threads: Random.natural(1, 20),
|
||||
replies: Random.natural(6, 100),
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
title: 'Site issues',
|
||||
threads: Random.natural(1, 20),
|
||||
replies: Random.natural(6, 100),
|
||||
last: {
|
||||
id: id++,
|
||||
mp: genMp(),
|
||||
title: Random.title(5, 10),
|
||||
user_name: Random.name(),
|
||||
time: '1d ago',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const THREAD: any[] = new Array(20).fill({}).map((v, idx) => ({
|
||||
id: id++,
|
||||
title: Random.title(5, 10),
|
||||
replies: Random.natural(1, 1000),
|
||||
label: idx % 2 === 0 && Random.boolean() ? genLabel() : null,
|
||||
category_id: Random.natural(1, 9),
|
||||
last: {
|
||||
id: id++,
|
||||
mp: genMp(),
|
||||
title: Random.title(5, 10),
|
||||
user_name: Random.name(),
|
||||
time: '1d ago',
|
||||
},
|
||||
}));
|
||||
|
||||
const REPLIES: any[] = new Array(20).fill({}).map((v, idx) => ({
|
||||
id: id++,
|
||||
content: Random.paragraph(),
|
||||
user: {
|
||||
name: Random.name(),
|
||||
mp: genMp(),
|
||||
posts: Random.natural(0, 1000),
|
||||
},
|
||||
time: Random.time(),
|
||||
like: Random.natural(0, 100),
|
||||
dislike: Random.natural(0, 10),
|
||||
}));
|
||||
|
||||
function get(params: any): any {
|
||||
let ret = deepCopy(THREAD);
|
||||
if (params.q) {
|
||||
ret = ret.filter((data: any) => data.name.indexOf(params.q) > -1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getIdx(itemId: number): number {
|
||||
itemId = +itemId;
|
||||
const idx = THREAD.findIndex((w) => w.id === itemId);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
function getCate(itemId: number): any {
|
||||
let item: any;
|
||||
const category: any = deepCopy(CATEGORY).find((w: any) => {
|
||||
item = w.list.find((l: any) => l.id === itemId);
|
||||
if (item) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
delete category.list;
|
||||
return item;
|
||||
}
|
||||
|
||||
export const FORUMS = {
|
||||
'/forum/category': CATEGORY,
|
||||
'/forum/thread/:id': (req: MockRequest) => {
|
||||
// list
|
||||
const pi = +(req.queryString.pi || 1);
|
||||
const ps = +(req.queryString.ps || 10);
|
||||
const data = get(req.queryString);
|
||||
return {
|
||||
category: getCate(+req.params.id),
|
||||
total: data.length,
|
||||
list: data.slice((pi - 1) * ps, pi * ps),
|
||||
};
|
||||
},
|
||||
'/forum/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
const item = {
|
||||
...THREAD[idx],
|
||||
time: '3 days ago',
|
||||
like: Random.natural(0, 100),
|
||||
view: Random.natural(0, 10000),
|
||||
user: {
|
||||
name: Random.name(),
|
||||
mp: genMp(),
|
||||
posts: Random.natural(0, 1000),
|
||||
},
|
||||
desc:
|
||||
'<p>' +
|
||||
new Array(Random.natural(1, 3))
|
||||
.fill('')
|
||||
.map((v) => Random.paragraph())
|
||||
.join('</p><p>') +
|
||||
'</p>',
|
||||
};
|
||||
item.category = getCate(item.category_id);
|
||||
return item;
|
||||
},
|
||||
'/forum/:id/replies': (req: MockRequest) => {
|
||||
const pi = +(req.queryString.pi || 1);
|
||||
const ps = +(req.queryString.ps || 10);
|
||||
return {
|
||||
total: REPLIES.length,
|
||||
list: REPLIES.slice((pi - 1) * ps, pi * ps),
|
||||
};
|
||||
},
|
||||
|
||||
'POST /forum': (req: MockRequest) => {
|
||||
const itemId = req.body.id || 0;
|
||||
if (itemId > 0) {
|
||||
const idx = getIdx(itemId);
|
||||
THREAD[idx] = { ...THREAD[idx], ...req.body };
|
||||
return { msg: 'ok', item: THREAD[idx] };
|
||||
}
|
||||
|
||||
const item = { ...req.body, id: THREAD.sort((a, b) => b.id - a.id)[0].id + 1 };
|
||||
THREAD.push(item);
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'DELETE /forum/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
THREAD.splice(idx, 1);
|
||||
return { msg: 'ok' };
|
||||
},
|
||||
};
|
||||
76
_mock/_geo.ts
Normal file
76
_mock/_geo.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { MockRequest } from '@delon/mock';
|
||||
|
||||
const DATA = [
|
||||
{
|
||||
name: '上海',
|
||||
id: '310000',
|
||||
},
|
||||
{
|
||||
name: '市辖区',
|
||||
id: '310100',
|
||||
},
|
||||
{
|
||||
name: '北京',
|
||||
id: '110000',
|
||||
},
|
||||
{
|
||||
name: '市辖区',
|
||||
id: '110100',
|
||||
},
|
||||
{
|
||||
name: '浙江省',
|
||||
id: '330000',
|
||||
},
|
||||
{
|
||||
name: '杭州市',
|
||||
id: '330100',
|
||||
},
|
||||
{
|
||||
name: '宁波市',
|
||||
id: '330200',
|
||||
},
|
||||
{
|
||||
name: '温州市',
|
||||
id: '330300',
|
||||
},
|
||||
{
|
||||
name: '嘉兴市',
|
||||
id: '330400',
|
||||
},
|
||||
{
|
||||
name: '湖州市',
|
||||
id: '330500',
|
||||
},
|
||||
{
|
||||
name: '绍兴市',
|
||||
id: '330600',
|
||||
},
|
||||
{
|
||||
name: '金华市',
|
||||
id: '330700',
|
||||
},
|
||||
{
|
||||
name: '衢州市',
|
||||
id: '330800',
|
||||
},
|
||||
{
|
||||
name: '舟山市',
|
||||
id: '330900',
|
||||
},
|
||||
{
|
||||
name: '台州市',
|
||||
id: '331000',
|
||||
},
|
||||
{
|
||||
name: '丽水市',
|
||||
id: '331100',
|
||||
},
|
||||
];
|
||||
|
||||
export const GEOS = {
|
||||
'/geo/province': () => DATA.filter(w => w.id.endsWith('0000')),
|
||||
'/geo/:id': (req: MockRequest) => {
|
||||
const pid = (req.params.id || '310000').slice(0, 2);
|
||||
return DATA.filter(w => w.id.slice(0, 2) === pid && !w.id.endsWith('0000'));
|
||||
},
|
||||
};
|
||||
103
_mock/_img.ts
Normal file
103
_mock/_img.ts
Normal file
@ -0,0 +1,103 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { deepCopy } from '@delon/util';
|
||||
import { genMp } from './utils';
|
||||
|
||||
interface ImgCat {
|
||||
id: number;
|
||||
parent_id: number;
|
||||
title: string;
|
||||
}
|
||||
interface Img {
|
||||
cat_id: number;
|
||||
id: number;
|
||||
title: string;
|
||||
mp: string;
|
||||
size: number;
|
||||
width: number;
|
||||
height: number;
|
||||
created: Date;
|
||||
}
|
||||
|
||||
const CAT: ImgCat[] = [
|
||||
{ id: 1, parent_id: 0, title: '店铺' },
|
||||
{ id: 2, parent_id: 1, title: '产品图' },
|
||||
{ id: 3, parent_id: 1, title: '品牌图' },
|
||||
{ id: 4, parent_id: 0, title: '营销' },
|
||||
{ id: 5, parent_id: 4, title: '双11' },
|
||||
{ id: 6, parent_id: 4, title: '日常' },
|
||||
{ id: 7, parent_id: 0, title: '其他' },
|
||||
];
|
||||
const DATA: Img[] = [];
|
||||
|
||||
for (let i = 1; i <= 50; i += 1) {
|
||||
DATA.push(gen(i));
|
||||
}
|
||||
|
||||
function gen(i: number): any {
|
||||
return {
|
||||
cat_id: [1, 2, 3, 4, 5, 6, 7][Math.floor(Math.random() * 10) % 7],
|
||||
id: i * 10000,
|
||||
title: `title ${i}`,
|
||||
mp: genMp(),
|
||||
size: Math.floor(Math.random() * 1000) % 1000,
|
||||
width: Math.floor(Math.random() * 1000) % 1000,
|
||||
height: Math.floor(Math.random() * 1000) % 1000,
|
||||
created: new Date(),
|
||||
};
|
||||
}
|
||||
|
||||
function get(params: any): any {
|
||||
let ret = deepCopy(DATA);
|
||||
const cat_id = +(params.cat_id || '0');
|
||||
if (cat_id > 0) {
|
||||
ret = ret.filter((data: any) => data.cat_id === cat_id);
|
||||
}
|
||||
if (params.q) {
|
||||
ret = ret.filter((data: any) => data.title.indexOf(params.q) > -1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getIdx(id: number): number {
|
||||
id = +id;
|
||||
const idx = DATA.findIndex((w) => w.id === id);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
export const IMGS = {
|
||||
'/img/cat': () => deepCopy(CAT),
|
||||
'/img': (req: MockRequest) => {
|
||||
const pi = +(req.queryString.pi || 1);
|
||||
const ps = +(req.queryString.ps || 10);
|
||||
const data = get(req.queryString);
|
||||
return {
|
||||
total: data.length,
|
||||
list: data.slice((pi - 1) * ps, pi * ps),
|
||||
};
|
||||
},
|
||||
'POST /img': (req: MockRequest) => {
|
||||
const id = req.body.id || 0;
|
||||
if (id > 0) {
|
||||
const idx = getIdx(id);
|
||||
DATA[idx] = { ...DATA[idx], ...req.body };
|
||||
return { msg: 'ok', item: DATA[idx] };
|
||||
}
|
||||
|
||||
const item = Object.assign(gen(DATA.sort((a, b) => b.id - a.id)[0].id + 1), req.body);
|
||||
DATA.push(item);
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'/img/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
const item = { ...DATA[idx], ...req.body };
|
||||
return item;
|
||||
},
|
||||
'DELETE /img/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
DATA.splice(idx, 1);
|
||||
return { msg: 'ok' };
|
||||
},
|
||||
};
|
||||
62
_mock/_log.ts
Normal file
62
_mock/_log.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { deepCopy } from '@delon/util';
|
||||
|
||||
const DATA: any[] = [];
|
||||
|
||||
for (let i = 1; i <= 20; i += 1) {
|
||||
DATA.push({
|
||||
id: i,
|
||||
name: 'cms',
|
||||
level: ['error', 'warning', 'info'][Math.floor(Math.random() * 10) % 3],
|
||||
path: `/home/${i}`,
|
||||
title: `未知报告 ${i}`,
|
||||
data: `Uncaught Error: test-${i}\nat <anonymous>:1:7\nat <anonymous>:1:7\nat <anonymous>:1:7`,
|
||||
created: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
function getIdx(id: number): number {
|
||||
const idx = DATA.findIndex((w) => w.id === id);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
function get(params: any): any {
|
||||
let ret = deepCopy(DATA);
|
||||
if (params.q) {
|
||||
ret = ret.filter((data: any) => data.title.indexOf(params.q) > -1);
|
||||
}
|
||||
if (params.level) {
|
||||
ret = ret.filter((data: any) => data.level.indexOf(params.level) > -1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function del(params: any): any {
|
||||
const id = params.id || 0;
|
||||
if (id > 0) {
|
||||
DATA.splice(getIdx(id), 1);
|
||||
} else {
|
||||
get(params).forEach((w: any) => {
|
||||
del({ id: w.id });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const LOGS = {
|
||||
'/log': (req: MockRequest) => {
|
||||
const pi = +(req.queryString.pi || 1);
|
||||
const ps = +(req.queryString.ps || 10);
|
||||
const data = get(req.queryString);
|
||||
return {
|
||||
total: data.length,
|
||||
list: data.slice((pi - 1) * ps, pi * ps),
|
||||
};
|
||||
},
|
||||
'DELETE /log': (req: MockRequest) => {
|
||||
del(req.queryString);
|
||||
return { msg: 'ok' };
|
||||
},
|
||||
};
|
||||
109
_mock/_menu.ts
Normal file
109
_mock/_menu.ts
Normal file
@ -0,0 +1,109 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { Menu } from '@delon/theme';
|
||||
import { deepCopy } from '@delon/util';
|
||||
|
||||
const DATA: Menu[] = [
|
||||
{
|
||||
id: 1,
|
||||
parent_id: 0,
|
||||
text: '主导航',
|
||||
i18n: 'menu.main',
|
||||
group: true,
|
||||
hideInBreadcrumb: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
parent_id: 1,
|
||||
text: '仪表盘',
|
||||
i18n: 'menu.dashboard',
|
||||
icon: 'dashboard',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
parent_id: 2,
|
||||
text: '分析页',
|
||||
link: '/dashboard/analysis',
|
||||
i18n: 'menu.dashboard.analysis',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
parent_id: 2,
|
||||
text: '监控页',
|
||||
link: '/dashboard/monitor',
|
||||
i18n: 'menu.dashboard.monitor',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
parent_id: 2,
|
||||
text: '工作台',
|
||||
link: '/dashboard/workplace',
|
||||
i18n: 'menu.dashboard.workplace',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
parent_id: 0,
|
||||
text: 'Pro',
|
||||
i18n: 'menu.pro',
|
||||
group: true,
|
||||
hideInBreadcrumb: true,
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
parent_id: 6,
|
||||
text: 'Form Page',
|
||||
i18n: 'menu.form',
|
||||
link: '/pro/form',
|
||||
icon: 'anticon anticon-edit',
|
||||
hideInBreadcrumb: true,
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
parent_id: 6,
|
||||
text: 'Basic Form',
|
||||
link: '/pro/form/basic-form',
|
||||
i18n: 'menu.form.basicform',
|
||||
shortcut: true,
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
parent_id: 6,
|
||||
text: 'Step Form',
|
||||
link: '/pro/form/step-form',
|
||||
i18n: 'menu.form.stepform',
|
||||
},
|
||||
];
|
||||
|
||||
function getIdx(id: number): number {
|
||||
id = +id;
|
||||
const idx = DATA.findIndex((w) => w.id === id);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
export const MENUS = {
|
||||
'/menus': () => deepCopy(DATA),
|
||||
'POST /menus': (req: MockRequest) => {
|
||||
const id = req.body.id || 0;
|
||||
if (id > 0) {
|
||||
const idx = getIdx(id);
|
||||
DATA[idx] = { ...DATA[idx], ...req.body };
|
||||
return { msg: 'ok', item: DATA[idx] };
|
||||
}
|
||||
|
||||
const item = { ...req.body, id: DATA.sort((a, b) => b.id - a.id)[0].id + 1 };
|
||||
DATA.push(item);
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'DELETE /menus/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
DATA.splice(idx, 1);
|
||||
return { msg: 'ok' };
|
||||
},
|
||||
'POST /menus/move': (req: MockRequest) => {
|
||||
const idx = getIdx(req.body.from || 0);
|
||||
DATA[idx].parent_id = req.body.to || 0;
|
||||
return { msg: 'ok', item: DATA[idx] };
|
||||
},
|
||||
};
|
||||
917
_mock/_other.ts
Normal file
917
_mock/_other.ts
Normal file
@ -0,0 +1,917 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { deepCopy } from '@delon/util';
|
||||
import format from 'date-fns/format';
|
||||
import getDaysInMonth from 'date-fns/getDaysInMonth';
|
||||
import startOfMonth from 'date-fns/startOfMonth';
|
||||
import { Random } from 'mockjs';
|
||||
|
||||
import { genArr, genBigMp, genColorName, genData, genLabel, genMp, genName, genTag } from './utils';
|
||||
|
||||
let ID = 1;
|
||||
const DATA: any = {
|
||||
kanban: null,
|
||||
task: null,
|
||||
email: null,
|
||||
project: null,
|
||||
client: null,
|
||||
contact: null,
|
||||
pricing: null,
|
||||
billing: null,
|
||||
course: null,
|
||||
chat: null,
|
||||
gallery: null,
|
||||
article: null,
|
||||
voting: null,
|
||||
invoice: null,
|
||||
faq: null,
|
||||
calendar: null,
|
||||
quick: null,
|
||||
dd: null
|
||||
};
|
||||
|
||||
function getIdx(type: string, id: number): number {
|
||||
id = +id;
|
||||
const idx = DATA[type].findIndex((w: any) => w.id === id);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
function save(type: string, body: any): any {
|
||||
const id = body.id || 0;
|
||||
if (id > 0) {
|
||||
const idx = getIdx(type, id);
|
||||
DATA[type][idx] = { ...DATA[type][idx], ...body };
|
||||
return { msg: 'ok', item: DATA[type][idx], type: 'edit' };
|
||||
}
|
||||
|
||||
const item = { ...body, id: DATA[type].sort((a: any, b: any) => b.id - a.id)[0].id + 1 };
|
||||
(DATA[type] as any[]).splice(0, 0, item);
|
||||
return { msg: 'ok', item, type: 'add' };
|
||||
}
|
||||
|
||||
function del(type: string, p: any): any {
|
||||
const cid = +(p.cid || '0');
|
||||
let list: any[] = DATA[type];
|
||||
if (cid > 0) {
|
||||
list = DATA[type].find((w: any) => w.id === cid).list;
|
||||
}
|
||||
|
||||
const idx = list.findIndex(w => w.id === p.id);
|
||||
list.splice(idx, 1);
|
||||
return { msg: 'ok' };
|
||||
}
|
||||
|
||||
function genHtml(): string {
|
||||
return `<p>${new Array(Random.natural(1, 3))
|
||||
.fill('')
|
||||
.map(v => Random.sentence())
|
||||
.join('</p><p>')}</p>`;
|
||||
}
|
||||
|
||||
function attachements(): any {
|
||||
return new Array(Random.natural(2, 6)).fill({}).map((v, idx) => {
|
||||
const item = {
|
||||
url: Random.url(),
|
||||
type: genArr(['jpg', 'zip', 'pdf']),
|
||||
filename: Random.name(false),
|
||||
size: genArr(['100KB', '980KB', '1.56MB'])
|
||||
};
|
||||
if (item.type === 'jpg') {
|
||||
item.url = genBigMp();
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
function genPage(type: string, queryString: any, qField: string = 'name'): any {
|
||||
const pi = +(queryString.pi || 1);
|
||||
const ps = +(queryString.ps || 10);
|
||||
// data
|
||||
let data = deepCopy(DATA[type]);
|
||||
if (queryString.q) {
|
||||
data = data.filter((data: any) => data[qField].indexOf(queryString.q) > -1);
|
||||
}
|
||||
return {
|
||||
total: data.length,
|
||||
list: data.slice((pi - 1) * ps, pi * ps)
|
||||
};
|
||||
}
|
||||
|
||||
// #region kanban
|
||||
|
||||
function kanbanList(): any {
|
||||
if (DATA.kanban) {
|
||||
return DATA.kanban;
|
||||
}
|
||||
const res: any[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'To Do',
|
||||
list: [],
|
||||
color: '#fadb14',
|
||||
icon: 'warning'
|
||||
},
|
||||
{ id: 2, title: 'In progress', color: '#1890ff', icon: 'tool', list: [] },
|
||||
{ id: 3, title: 'Done', color: '#52c41a', icon: 'check-circle', list: [] },
|
||||
{ id: 4, title: 'Gone', color: '#f5222d', icon: 'delete', list: [] }
|
||||
];
|
||||
for (const i of res) {
|
||||
i.list = new Array(Random.natural(2, 6)).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
title: Random.ctitle(3, 4),
|
||||
content: Random.ctitle(0, 50),
|
||||
attachement: Random.boolean() && Random.boolean() && Random.boolean()
|
||||
}));
|
||||
}
|
||||
// new
|
||||
if (res[0].list.length > 0) {
|
||||
res[0].list[Random.natural(0, res[0].list.length - 1)].label = {
|
||||
color: 'green',
|
||||
text: 'Clients'
|
||||
};
|
||||
}
|
||||
if (res[1].list.length > 0) {
|
||||
res[1].list[Random.natural(0, res[1].list.length - 1)].label = {
|
||||
color: 'red',
|
||||
text: 'Important'
|
||||
};
|
||||
}
|
||||
if (res[2].list.length > 0) {
|
||||
res[2].list[Random.natural(0, res[2].list.length - 1)].label = {
|
||||
color: 'blue',
|
||||
text: 'Other'
|
||||
};
|
||||
}
|
||||
// labels
|
||||
DATA.kanban = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region task
|
||||
|
||||
function taskList(): any {
|
||||
if (DATA.task) {
|
||||
return DATA.task;
|
||||
}
|
||||
const res: any[] = [
|
||||
{ id: 1, title: 'Today', list: [] },
|
||||
{ id: 2, title: 'Tomorrow', list: [] },
|
||||
{ id: 3, title: 'Next week', list: [] }
|
||||
];
|
||||
for (const i of res) {
|
||||
i.list = new Array(Random.natural(2, 8)).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
title: Random.ctitle(3, 16),
|
||||
due: i.id === 1 && Random.boolean() ? `${Random.natural(1, 59)} ${Random.boolean() ? 'mins' : 'hours'} left` : null
|
||||
}));
|
||||
}
|
||||
// new
|
||||
if (res[0].list.length > 0) {
|
||||
res[0].list[Random.natural(0, res[0].list.length - 1)].label = {
|
||||
color: 'green',
|
||||
text: 'Clients'
|
||||
};
|
||||
}
|
||||
if (res[1].list.length > 0) {
|
||||
res[1].list[Random.natural(0, res[1].list.length - 1)].label = {
|
||||
color: 'red',
|
||||
text: 'Important'
|
||||
};
|
||||
res[0].list[Random.natural(0, res[0].list.length - 1)].done = true;
|
||||
}
|
||||
if (res[2].list.length > 0) {
|
||||
res[2].list[Random.natural(0, res[2].list.length - 1)].label = {
|
||||
color: 'blue',
|
||||
text: 'Other'
|
||||
};
|
||||
res[0].list[Random.natural(0, res[0].list.length - 1)].done = true;
|
||||
}
|
||||
// labels
|
||||
DATA.task = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region email
|
||||
|
||||
function emailList(queryString: any): any {
|
||||
if (DATA.email) {
|
||||
return genPage('email', queryString, 'subject');
|
||||
}
|
||||
const res: any[] = new Array(20).fill({}).map((v, idx) => ({
|
||||
id: ID++,
|
||||
from: Random.email(),
|
||||
from_name: genName(),
|
||||
to: Random.email(),
|
||||
to_name: Random.name(),
|
||||
cc: [Random.email(), Random.email()],
|
||||
subject: Random.title(1, 6),
|
||||
body: Random.paragraph(),
|
||||
read: idx % 2 === 0 && Random.boolean(),
|
||||
star: Random.boolean(),
|
||||
label: genLabel(),
|
||||
attach: idx % 3 === 0 && Random.boolean(),
|
||||
time: `1${Random.boolean() ? 'h' : 'd'} ago`
|
||||
}));
|
||||
// labels
|
||||
DATA.email = res;
|
||||
return genPage('email', queryString, 'subject');
|
||||
}
|
||||
|
||||
function emailGet(id: number): any {
|
||||
const idx = getIdx('email', id || 0);
|
||||
const item = { ...DATA.email[idx], mp: genMp(), desc: genHtml(), attachements: attachements() };
|
||||
return item;
|
||||
}
|
||||
// #endregion
|
||||
|
||||
// #region project
|
||||
|
||||
function projectList(): any {
|
||||
if (DATA.project) {
|
||||
return DATA.project;
|
||||
}
|
||||
const res: any[] = new Array(5).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
title: genArr(['UI update', 'Web Design', 'Pro Design', 'Ng Alain', 'Delon', 'SEO']),
|
||||
status: idx % 2 ? genArr(['active', 'pending', 'complete']) : 'active',
|
||||
task: {
|
||||
process: Random.natural(1, 100),
|
||||
opened: Random.natural(1, 100),
|
||||
completed: Random.natural(1, 100)
|
||||
},
|
||||
remark: Random.title(5, 10),
|
||||
created: Random.date(),
|
||||
deadline: Random.date(),
|
||||
tean: new Array(Random.natural(1, 6)).fill({}).map(() => ({
|
||||
name: genName(),
|
||||
mp: genMp()
|
||||
})),
|
||||
leaders: new Array(Random.natural(1, 2)).fill({}).map(() => ({
|
||||
name: genName(),
|
||||
mp: genMp()
|
||||
})),
|
||||
participants: new Array(Random.natural(1, 6)).fill({}).map(() => ({
|
||||
name: Random.name(),
|
||||
mp: genMp()
|
||||
}))
|
||||
}));
|
||||
// labels
|
||||
DATA.project = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
function projectGet(id: number): any {
|
||||
const idx = getIdx('project', id || 0);
|
||||
const item = {
|
||||
...DATA.project[idx],
|
||||
user_name: genName(),
|
||||
desc: genHtml(),
|
||||
attachements: attachements(),
|
||||
tasks: DATA.task,
|
||||
discussions: new Array(Random.natural(3, 8)).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
user_avatar: genMp(),
|
||||
user_name: genName(),
|
||||
time: Random.datetime(),
|
||||
content: Random.paragraph(1, 1)
|
||||
})),
|
||||
activities: new Array(Random.natural(3, 12)).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
user_avatar: genMp(),
|
||||
user_name: genName(),
|
||||
time: Random.datetime(),
|
||||
type: idx % 2 === 0 ? genArr(['add', 'completed', 'assigned']) : 'push',
|
||||
commit: Random.natural(10000, 99999),
|
||||
assigne_name: Random.name(),
|
||||
message: Random.title()
|
||||
}))
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region billing
|
||||
|
||||
function billingList(queryString: any): any {
|
||||
if (DATA.billing) {
|
||||
return genPage('billing', queryString, 'client');
|
||||
}
|
||||
const res: any[] = new Array(11).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
order: `FR0${Random.natural(10, 99)}`,
|
||||
client: genArr(['Google', 'Alibaba', 'Tencent']),
|
||||
fee: Random.float(0, 9.0),
|
||||
amount: Random.float(0.1, 99999.0),
|
||||
date: Random.now('day'),
|
||||
status: idx % 2 ? genArr(['Completed', 'Pending', 'Rejected']) : 'Completed',
|
||||
auth_code: Random.natural(100000000),
|
||||
address: (Random as any).county(true),
|
||||
first_name: Random.first(),
|
||||
last_name: Random.last(),
|
||||
country: 'China'
|
||||
}));
|
||||
// labels
|
||||
DATA.billing = res;
|
||||
return genPage('billing', queryString, 'client');
|
||||
}
|
||||
|
||||
function billingGet(id: number): any {
|
||||
const idx = getIdx('billing', id || 0);
|
||||
const item = {
|
||||
...DATA.billing[idx],
|
||||
messages: new Array(Random.natural(0, 5)).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
time: `${Random.natural(1, 6)} day ago`,
|
||||
message: Random.paragraph(1, 1)
|
||||
}))
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region contact
|
||||
|
||||
function contactList(queryString: any): any {
|
||||
if (DATA.contact) {
|
||||
return genPage('contact', queryString, 'contact');
|
||||
}
|
||||
const res: any[] = new Array(11).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
mp: genMp(),
|
||||
name: genName(),
|
||||
user_name: Random.name(false),
|
||||
company: Random.title(1, 3),
|
||||
email: Random.email(),
|
||||
tel: Random.natural(10000000000, 16000000000)
|
||||
}));
|
||||
// labels
|
||||
DATA.contact = res;
|
||||
return genPage('contact', queryString, 'company');
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region pricing
|
||||
|
||||
function pricingList(): any {
|
||||
if (DATA.pricing) {
|
||||
return DATA.pricing;
|
||||
}
|
||||
const res: any = {
|
||||
prices: [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Basic',
|
||||
icon: 'shop',
|
||||
mo: 12,
|
||||
yr: 12 * 12,
|
||||
user: 5,
|
||||
project: 5,
|
||||
space: '100GB'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Company',
|
||||
icon: 'bank',
|
||||
mo: 25,
|
||||
yr: 25 * 12,
|
||||
user: 30,
|
||||
project: 150,
|
||||
space: '300GB'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Enterprise',
|
||||
icon: 'crown',
|
||||
mo: 50,
|
||||
yr: 50 * 12,
|
||||
user: -1,
|
||||
project: -1,
|
||||
space: '1000GB'
|
||||
}
|
||||
],
|
||||
faq: [
|
||||
{
|
||||
q: 'Can I cancel at anytime?',
|
||||
a: 'Yes, you can cancel anytime no questions are asked while you cancel but we would highly appreciate if you will give us some feedback.'
|
||||
},
|
||||
{
|
||||
q: 'My team has credits. How do we use them?',
|
||||
a: 'Once your team signs up for a subscription plan. enim eiusmod high life accusamus eoset dignissimos.'
|
||||
},
|
||||
{
|
||||
q: `How does Front's pricing work?`,
|
||||
a: 'Our subscriptions are tiered. based on the number of people enim eiusmod high life accusamus terry richardson ad squid.'
|
||||
},
|
||||
{
|
||||
q: 'How secure is Front?',
|
||||
a: 'Protecting the data you trust to Front is our first priority. at vero eoset dignissimos ducimus qui blanditiis.'
|
||||
},
|
||||
{
|
||||
q: 'Do you offer discounts?',
|
||||
a: `We've built in discounts at each tier for teams. leggings occaecat craft beer farm-to-table. raw denim aesthetic synth nesciunt.`
|
||||
},
|
||||
{
|
||||
q: 'What is your refund policy?',
|
||||
a: 'We do not offer refunds apart leggings occaecat craft beer farm-to-table. raw leggings occaecat craft.'
|
||||
}
|
||||
]
|
||||
};
|
||||
// labels
|
||||
DATA.pricing = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region client
|
||||
|
||||
function clientList(queryString: any): any {
|
||||
if (DATA.client) {
|
||||
return genPage('client', queryString, 'company');
|
||||
}
|
||||
const res: any[] = new Array(11).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
mp: genMp(),
|
||||
name: genName(),
|
||||
user_name: Random.name(false),
|
||||
company: Random.title(1, 3),
|
||||
email: Random.email(),
|
||||
tel: Random.natural(10000000000, 16000000000),
|
||||
status: idx % 2 ? genArr(['active', 'pending', 'progress']) : 'active'
|
||||
}));
|
||||
// labels
|
||||
DATA.client = res;
|
||||
return genPage('client', queryString, 'company');
|
||||
}
|
||||
|
||||
function clientGet(id: number): any {
|
||||
const idx = getIdx('client', id || 0);
|
||||
const item = {
|
||||
...DATA.client[idx],
|
||||
messages: new Array(Random.natural(0, 5)).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
time: `${Random.natural(1, 6)} day ago`,
|
||||
message: Random.paragraph(1, 1)
|
||||
}))
|
||||
};
|
||||
return item;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region course
|
||||
|
||||
function courseList(queryString: any): any {
|
||||
if (DATA.course) {
|
||||
return genPage('course', queryString, 'title');
|
||||
}
|
||||
const res: any[] = new Array(10).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
mp: genBigMp(),
|
||||
tags: genTag(),
|
||||
price: idx === 0 ? 0 : Random.natural(0, 100),
|
||||
title: Random.title(2, 5),
|
||||
remark: Random.paragraph(1, 1),
|
||||
star: genArr([4, 4.5, 5]),
|
||||
hour: Random.natural(10, 99)
|
||||
}));
|
||||
// labels
|
||||
DATA.course = res;
|
||||
return genPage('course', queryString, 'title');
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region chat
|
||||
|
||||
function chatList(): any {
|
||||
if (DATA.chat) {
|
||||
return DATA.chat;
|
||||
}
|
||||
const res: any = {
|
||||
users: new Array(10).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
mp: genMp(),
|
||||
name: genName(),
|
||||
count: idx % 3 === 0 ? Random.natural(0, 5) : 0,
|
||||
online: idx < 5 ? true : false,
|
||||
unread: Random.boolean() && Random.boolean() ? Random.natural(0, 5) : 0
|
||||
}))
|
||||
};
|
||||
// labels
|
||||
DATA.chat = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region gallery
|
||||
|
||||
function galleryList(): any {
|
||||
if (DATA.gallery) {
|
||||
return DATA.gallery;
|
||||
}
|
||||
const res: any = new Array(16).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
url: genBigMp(),
|
||||
title: Random.title(),
|
||||
type: genArr(['Nature', 'Beach', 'Animal', 'Other'])
|
||||
}));
|
||||
// labels
|
||||
DATA.gallery = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region article
|
||||
|
||||
function articleList(queryString: any): any {
|
||||
if (DATA.article) {
|
||||
return genPage('article', queryString, 'title');
|
||||
}
|
||||
const res: any[] = new Array(11).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
mp: genMp(),
|
||||
name: genName(),
|
||||
title: Random.ctitle(),
|
||||
likes: Random.natural(0, 1000),
|
||||
comments: Random.natural(0, 1000),
|
||||
created: Random.now('day'),
|
||||
status: idx % 2 ? genArr(['Published', 'Draft', 'Deleted']) : 'Published'
|
||||
}));
|
||||
// labels
|
||||
DATA.article = res;
|
||||
return genPage('article', queryString, 'title');
|
||||
}
|
||||
|
||||
function articleGet(id: number): any {
|
||||
const idx = getIdx('article', id || 0);
|
||||
const item = { ...DATA.article[idx] };
|
||||
return item;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region voting
|
||||
|
||||
function votingList(queryString: any): any {
|
||||
if (DATA.voting) {
|
||||
return genPage('voting', queryString, 'title');
|
||||
}
|
||||
const res: any[] = new Array(11).fill({}).map((v, idx) => ({
|
||||
id: idx + 1,
|
||||
voting: Random.integer(-10, 10000),
|
||||
title: Random.title(5, 10),
|
||||
content: Random.paragraph(),
|
||||
likes: Random.natural(0, 1000),
|
||||
created: Random.now('day')
|
||||
}));
|
||||
// labels
|
||||
DATA.voting = res;
|
||||
return genPage('voting', queryString, 'title');
|
||||
}
|
||||
|
||||
function votingSave(req: any): any {
|
||||
const idx = getIdx('voting', req.id || 0);
|
||||
DATA.voting[idx].value += req.voting;
|
||||
return { msg: 'ok', item: DATA.voting[idx] };
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region voting
|
||||
|
||||
function invoice(): any {
|
||||
if (DATA.invoice) {
|
||||
return deepCopy(DATA.invoice);
|
||||
}
|
||||
const res: any = {
|
||||
id: Random.integer(10000, 99999),
|
||||
zone: 'Mountain View, CA 94043 United States',
|
||||
address: '1600 Amphitheatre Parkway',
|
||||
tel: '15900000000, +86 (021) 99999999',
|
||||
date: genData(0),
|
||||
to: {
|
||||
company: 'XXX Company LTD',
|
||||
zone: 'Mountain View, CA 94043 United States',
|
||||
address: '1600 Amphitheatre Parkway',
|
||||
tel: '15900000000, +86 (021) 99999999',
|
||||
email: 'cipchk@qq.com'
|
||||
},
|
||||
payment: {
|
||||
total: 0,
|
||||
bank: 'XXXX Bank',
|
||||
country: 'China',
|
||||
city: 'Shang Hai',
|
||||
address: 'xxx xxxx',
|
||||
code: '012384'
|
||||
},
|
||||
wares: [
|
||||
{
|
||||
id: 1,
|
||||
title: Random.title(),
|
||||
remark: Random.title(),
|
||||
price: +Random.float(0.1, 999).toFixed(2),
|
||||
num: +Random.natural(1, 10)
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: Random.title(),
|
||||
remark: Random.title(),
|
||||
price: +Random.float(0.1, 999).toFixed(2),
|
||||
num: +Random.natural(1, 10)
|
||||
}
|
||||
],
|
||||
note: Random.paragraph()
|
||||
};
|
||||
// total
|
||||
res.wares.forEach((i: any) => {
|
||||
i.total = +(i.price * i.num).toFixed(2);
|
||||
});
|
||||
res.tax_rate = 0.2;
|
||||
res.total = +(res.wares as any[]).reduce((a, b) => (a += b.total), 0).toFixed(2);
|
||||
res.tax = +(res.total * 0.2).toFixed(2);
|
||||
res.payment_total = +(res.total + res.tax).toFixed(2);
|
||||
DATA.invoice = res;
|
||||
|
||||
return deepCopy(DATA.invoice);
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region faq
|
||||
|
||||
function faq(): any {
|
||||
if (DATA.faq) {
|
||||
return deepCopy(DATA.faq);
|
||||
}
|
||||
DATA.faq = new Array(6).fill({}).map((v, idx) => ({
|
||||
title: `Knowledge ${idx + 1}`,
|
||||
icon: 'question-circle',
|
||||
primary: idx < 3,
|
||||
remark: 'The list of FAQ',
|
||||
children: new Array(Random.natural(3, 6)).fill({}).map((v, idx) => ({
|
||||
active: idx === 0,
|
||||
q: 'What is a product key?',
|
||||
a: genHtml()
|
||||
}))
|
||||
}));
|
||||
|
||||
return deepCopy(DATA.faq);
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region calendar
|
||||
|
||||
function calendar(req: any): any {
|
||||
const cur = new Date(+req.time || new Date());
|
||||
const startDate = startOfMonth(cur);
|
||||
const max = getDaysInMonth(cur);
|
||||
const start = format(startDate, 'yyyy-MM');
|
||||
const now = format(new Date(), 'yyyy-MM-dd');
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
title: 'All Day Event',
|
||||
start: `${start}-1`,
|
||||
className: 'fc-event-danger fc-event-fill-warning'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Reporting',
|
||||
start: `${start}-7T13:30:00`,
|
||||
end: `${start}-7`,
|
||||
className: 'fc-event-success'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Company Trip',
|
||||
start: `${start}-12`,
|
||||
end: `${start}-14`,
|
||||
className: 'fc-event-primary'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: 'Product Release',
|
||||
start: `${start}-3`,
|
||||
end: `${start}-5`,
|
||||
className: 'fc-event-light fc-event-fill-primary'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: 'Repeating Event',
|
||||
start: `${start}-09T16:00:00`,
|
||||
className: 'fc-event-purple'
|
||||
},
|
||||
{ id: 6, title: 'Repeating Event', start: `${start}-11T16:00:00` },
|
||||
{
|
||||
id: 7,
|
||||
title: 'Meeting',
|
||||
start: `${now}T10:00:00`,
|
||||
end: `${now}T11:30:00`
|
||||
},
|
||||
{ id: 8, title: 'Lunch', start: `${now}T12:00:00` },
|
||||
{
|
||||
id: 9,
|
||||
title: 'Meeting',
|
||||
start: `${now}T14:00:00`,
|
||||
className: 'fc-event-warning'
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
title: 'Happy Hour',
|
||||
start: `${now}T17:30:00`,
|
||||
className: 'fc-event-success'
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
title: 'Dinner',
|
||||
start: `${now}T18:30:00`,
|
||||
className: 'fc-event-fill-danger fc-event-light'
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
title: 'Birthday Party',
|
||||
start: `${now}T21:00:00`,
|
||||
className: 'fc-event-primary'
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
title: 'Click for Ng Alain',
|
||||
url: 'https://ng-alain.com',
|
||||
start: `${start}-27`,
|
||||
className: 'fc-event-fill-success fc-event-light'
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
title: 'Repeating Event',
|
||||
start: `${start}-09T08:00:00`,
|
||||
className: 'fc-event-magenta'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region quick
|
||||
|
||||
function quick(): any {
|
||||
if (DATA.quick) {
|
||||
return deepCopy(DATA.quick);
|
||||
}
|
||||
DATA.quick = {
|
||||
notifications: new Array(6).fill({}).map(() => ({
|
||||
dot: genArr([
|
||||
{ icon: 'warning', bg: 'error' },
|
||||
{ icon: 'pie-chart', bg: 'primary' },
|
||||
{ icon: 'message', bg: 'success' },
|
||||
{ icon: 'bell', bg: 'cyan' }
|
||||
]),
|
||||
content: Random.title(5, 15),
|
||||
time: genArr(['01:01 PM', '09:00 AM', '18:56']),
|
||||
tags: genTag().join(',')
|
||||
})),
|
||||
actions: new Array(6).fill({}).map(() => ({
|
||||
bg: genColorName(),
|
||||
title: Random.title(2, 3),
|
||||
content: Random.title(5, 15)
|
||||
})),
|
||||
settings: {
|
||||
notification: true,
|
||||
audit_log: false,
|
||||
new_order: false,
|
||||
tracking_order: false,
|
||||
reports_order: true,
|
||||
new_customer: true,
|
||||
reporting_customer: true
|
||||
}
|
||||
};
|
||||
|
||||
return deepCopy(DATA.quick);
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region dd
|
||||
|
||||
function ddList(): any {
|
||||
if (DATA.dd) {
|
||||
return DATA.dd;
|
||||
}
|
||||
DATA.dd = [
|
||||
{
|
||||
name: 'total-sales',
|
||||
title: '总数-总销售额',
|
||||
enabled: true,
|
||||
params: { title: '总销售额', total: 100, week: 10, day: 11, daySales: 1000 }
|
||||
},
|
||||
{
|
||||
name: 'total-sales',
|
||||
title: '总数-总订单量',
|
||||
enabled: false,
|
||||
params: { title: '总订单量', total: 5500, week: 320, day: 5, daySales: 5422 }
|
||||
},
|
||||
{
|
||||
name: 'total-sales',
|
||||
title: '总数-总用户量',
|
||||
enabled: false,
|
||||
params: { title: '总用户量', total: 500, week: 80, day: 23, daySales: 6666 }
|
||||
},
|
||||
{
|
||||
name: 'total-sales',
|
||||
title: '总数-其他',
|
||||
enabled: false,
|
||||
params: { title: '其他', total: 200, week: 80, day: 23, daySales: 77777 }
|
||||
},
|
||||
{
|
||||
name: 'visits',
|
||||
title: '访问量',
|
||||
enabled: true,
|
||||
params: { url: '/chart' }
|
||||
},
|
||||
{
|
||||
name: 'effect',
|
||||
title: '访问量',
|
||||
enabled: true,
|
||||
params: { percent: 66, week: 11, day: 23 }
|
||||
},
|
||||
{
|
||||
name: 'gauge',
|
||||
title: '核销率',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
name: 'radar',
|
||||
title: '指数',
|
||||
enabled: true,
|
||||
params: { title: '贡献指数', url: '/chart' }
|
||||
},
|
||||
{
|
||||
name: 'activities',
|
||||
title: '动态',
|
||||
enabled: true,
|
||||
params: { title: '动态', url: '/api/activities' }
|
||||
}
|
||||
];
|
||||
return DATA.dd;
|
||||
}
|
||||
|
||||
function ddSave(req: any): any {
|
||||
DATA.dd = req;
|
||||
return { msg: 'ok' };
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
export const OTHERS = {
|
||||
'/kanban-board': kanbanList(),
|
||||
'DELETE /kanban-board': (req: MockRequest) => del('kanban', req.queryString),
|
||||
'/task': taskList(),
|
||||
'DELETE /task': (req: MockRequest) => del('task', req.queryString),
|
||||
'/email': (req: MockRequest) => emailList(req.queryString),
|
||||
'/email/:id': (req: MockRequest) => emailGet(+req.params.id),
|
||||
'DELETE /email': (req: MockRequest) => del('email', req.queryString),
|
||||
'/project': projectList(),
|
||||
'/project/:id': (req: MockRequest) => projectGet(+req.params.id),
|
||||
'DELETE /project': (req: MockRequest) => del('project', req.queryString),
|
||||
'/client': (req: MockRequest) => clientList(req.queryString),
|
||||
'/client/:id': (req: MockRequest) => clientGet(+req.params.id),
|
||||
'/contact': (req: MockRequest) => contactList(req.queryString),
|
||||
'DELETE /contact': (req: MockRequest) => del('contact', req.queryString),
|
||||
'/pricing': () => pricingList(),
|
||||
'/billing': (req: MockRequest) => billingList(req.queryString),
|
||||
'/course': (req: MockRequest) => courseList(req.queryString),
|
||||
'/chat': () => chatList(),
|
||||
'/chat/message': () => {
|
||||
const item: any = {
|
||||
type: Random.boolean() && Random.boolean() ? 'image' : 'text',
|
||||
dir: Random.boolean() ? 'left' : 'right'
|
||||
};
|
||||
item.msg = item.type === 'text' ? Random.paragraph(1, 1) : genBigMp();
|
||||
return item;
|
||||
},
|
||||
'/gallery': () => galleryList(),
|
||||
'/article': (req: MockRequest) => articleList(req.queryString),
|
||||
'/article/:id': (req: MockRequest) => articleGet(+req.params.id),
|
||||
'DELETE /article': (req: MockRequest) => del('article', req.queryString),
|
||||
'POST /article': (req: MockRequest) => save('article', req.body),
|
||||
'/voting': (req: MockRequest) => votingList(req.queryString),
|
||||
'POST /voting': (req: MockRequest) => votingSave(req.body),
|
||||
'/invoice': () => invoice(),
|
||||
'/faq': () => faq(),
|
||||
'/calendar': (req: MockRequest) => calendar(req.queryString),
|
||||
'/quick': () => quick(),
|
||||
'/dd': () => ddList(),
|
||||
'POST /dd': (req: MockRequest) => ddSave(req.body)
|
||||
};
|
||||
58
_mock/_permission.ts
Normal file
58
_mock/_permission.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { deepCopy } from '@delon/util';
|
||||
|
||||
interface Permission {
|
||||
id: number;
|
||||
parent_id: number;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export const PermissionData: Permission[] = [
|
||||
{ id: 1, parent_id: 0, text: '超级权限' },
|
||||
{ id: 2, parent_id: 0, text: '系统' },
|
||||
{ id: 3, parent_id: 2, text: '员工' },
|
||||
{ id: 4, parent_id: 2, text: '菜单' },
|
||||
{ id: 5, parent_id: 2, text: '权限' },
|
||||
{ id: 6, parent_id: 0, text: '订单' },
|
||||
{ id: 7, parent_id: 6, text: '列表' },
|
||||
{ id: 8, parent_id: 6, text: '导入订单' },
|
||||
{ id: 9, parent_id: 6, text: '打印快递单' },
|
||||
{ id: 10, parent_id: 9, text: '批量打印' },
|
||||
{ id: 11, parent_id: 6, text: '发货' },
|
||||
{ id: 12, parent_id: 11, text: '批量发货' },
|
||||
];
|
||||
|
||||
function getIdx(id: number): number {
|
||||
id = +id;
|
||||
const idx = PermissionData.findIndex((w) => w.id === id);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
export const PERMISSION = {
|
||||
'/permission': () => deepCopy(PermissionData),
|
||||
'POST /permission': (req: MockRequest) => {
|
||||
const id = req.body.id || 0;
|
||||
if (id > 0) {
|
||||
const idx = getIdx(id);
|
||||
PermissionData[idx] = { ...PermissionData[idx], ...req.body };
|
||||
return { msg: 'ok', item: PermissionData[idx] };
|
||||
}
|
||||
|
||||
const item = { ...req.body, id: PermissionData.sort((a, b) => b.id - a.id)[0].id + 1 };
|
||||
PermissionData.push(item);
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'DELETE /permission/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
PermissionData.splice(idx, 1);
|
||||
return { msg: 'ok' };
|
||||
},
|
||||
'POST /permission/move': (req: MockRequest) => {
|
||||
const idx = getIdx(req.body.from || 0);
|
||||
PermissionData[idx].parent_id = req.body.to || 0;
|
||||
return { msg: 'ok', item: PermissionData[idx] };
|
||||
},
|
||||
};
|
||||
61
_mock/_pois.ts
Normal file
61
_mock/_pois.ts
Normal file
@ -0,0 +1,61 @@
|
||||
export const POIS = {
|
||||
'/pois': {
|
||||
total: 2,
|
||||
list: [
|
||||
{
|
||||
id: 10000,
|
||||
user_id: 1,
|
||||
name: '测试品牌',
|
||||
branch_name: '测试分店',
|
||||
geo: 310105,
|
||||
country: '中国',
|
||||
province: '上海',
|
||||
city: '上海市',
|
||||
district: '长宁区',
|
||||
address: '中山公园',
|
||||
tel: '15900000000',
|
||||
categories: '美食,粤菜,湛江菜',
|
||||
lng: 121.41707989151003,
|
||||
lat: 31.218656214644792,
|
||||
recommend: '推荐品',
|
||||
special: '特色服务',
|
||||
introduction: '商户简介',
|
||||
open_time: '营业时间',
|
||||
avg_price: 260,
|
||||
reason: null,
|
||||
status: 1,
|
||||
status_str: '待审核',
|
||||
status_wx: 1,
|
||||
modified: 1505826527288,
|
||||
created: 1505826527288,
|
||||
},
|
||||
{
|
||||
id: 10001,
|
||||
user_id: 2,
|
||||
name: '测试品牌2',
|
||||
branch_name: '测试分店2',
|
||||
geo: 310105,
|
||||
country: '中国',
|
||||
province: '上海',
|
||||
city: '上海市',
|
||||
district: '长宁区',
|
||||
address: '中山公园',
|
||||
tel: '15900000000',
|
||||
categories: '美食,粤菜,湛江菜',
|
||||
lng: 121.41707989151003,
|
||||
lat: 31.218656214644792,
|
||||
recommend: '推荐品',
|
||||
special: '特色服务',
|
||||
introduction: '商户简介',
|
||||
open_time: '营业时间',
|
||||
avg_price: 260,
|
||||
reason: null,
|
||||
status: 1,
|
||||
status_str: '待审核',
|
||||
status_wx: 1,
|
||||
modified: 1505826527288,
|
||||
created: 1505826527288,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
152
_mock/_profile.ts
Normal file
152
_mock/_profile.ts
Normal file
@ -0,0 +1,152 @@
|
||||
const basicGoods = [
|
||||
{
|
||||
id: '1234561',
|
||||
name: '矿泉水 550ml',
|
||||
barcode: '12421432143214321',
|
||||
price: '2.00',
|
||||
num: '1',
|
||||
amount: '2.00',
|
||||
},
|
||||
{
|
||||
id: '1234562',
|
||||
name: '凉茶 300ml',
|
||||
barcode: '12421432143214322',
|
||||
price: '3.00',
|
||||
num: '2',
|
||||
amount: '6.00',
|
||||
},
|
||||
{
|
||||
id: '1234563',
|
||||
name: '好吃的薯片',
|
||||
barcode: '12421432143214323',
|
||||
price: '7.00',
|
||||
num: '4',
|
||||
amount: '28.00',
|
||||
},
|
||||
{
|
||||
id: '1234564',
|
||||
name: '特别好吃的蛋卷',
|
||||
barcode: '12421432143214324',
|
||||
price: '8.50',
|
||||
num: '3',
|
||||
amount: '25.50',
|
||||
},
|
||||
];
|
||||
|
||||
const basicProgress = [
|
||||
{
|
||||
key: '1',
|
||||
time: '2017-10-01 14:10',
|
||||
rate: '联系客户',
|
||||
status: 'processing',
|
||||
operator: '取货员 ID1234',
|
||||
cost: '5mins',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
time: '2017-10-01 14:05',
|
||||
rate: '取货员出发',
|
||||
status: 'success',
|
||||
operator: '取货员 ID1234',
|
||||
cost: '1h',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
time: '2017-10-01 13:05',
|
||||
rate: '取货员接单',
|
||||
status: 'success',
|
||||
operator: '取货员 ID1234',
|
||||
cost: '5mins',
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
time: '2017-10-01 13:00',
|
||||
rate: '申请审批通过',
|
||||
status: 'success',
|
||||
operator: '系统',
|
||||
cost: '1h',
|
||||
},
|
||||
{
|
||||
key: '5',
|
||||
time: '2017-10-01 12:00',
|
||||
rate: '发起退货申请',
|
||||
status: 'success',
|
||||
operator: '用户',
|
||||
cost: '5mins',
|
||||
},
|
||||
];
|
||||
|
||||
const advancedOperation1 = [
|
||||
{
|
||||
key: 'op1',
|
||||
type: '订购关系生效',
|
||||
name: '曲丽丽',
|
||||
status: 'agree',
|
||||
updatedAt: '2017-10-03 19:23:12',
|
||||
memo: '-',
|
||||
},
|
||||
{
|
||||
key: 'op2',
|
||||
type: '财务复审',
|
||||
name: '付小小',
|
||||
status: 'reject',
|
||||
updatedAt: '2017-10-03 19:23:12',
|
||||
memo: '不通过原因',
|
||||
},
|
||||
{
|
||||
key: 'op3',
|
||||
type: '部门初审',
|
||||
name: '周毛毛',
|
||||
status: 'agree',
|
||||
updatedAt: '2017-10-03 19:23:12',
|
||||
memo: '-',
|
||||
},
|
||||
{
|
||||
key: 'op4',
|
||||
type: '提交订单',
|
||||
name: '林东东',
|
||||
status: 'agree',
|
||||
updatedAt: '2017-10-03 19:23:12',
|
||||
memo: '很棒',
|
||||
},
|
||||
{
|
||||
key: 'op5',
|
||||
type: '创建订单',
|
||||
name: '汗牙牙',
|
||||
status: 'agree',
|
||||
updatedAt: '2017-10-03 19:23:12',
|
||||
memo: '-',
|
||||
},
|
||||
];
|
||||
|
||||
const advancedOperation2 = [
|
||||
{
|
||||
key: 'op1',
|
||||
type: '订购关系生效',
|
||||
name: '曲丽丽',
|
||||
status: 'agree',
|
||||
updatedAt: '2017-10-03 19:23:12',
|
||||
memo: '-',
|
||||
},
|
||||
];
|
||||
|
||||
const advancedOperation3 = [
|
||||
{
|
||||
key: 'op1',
|
||||
type: '创建订单',
|
||||
name: '汗牙牙',
|
||||
status: 'agree',
|
||||
updatedAt: '2017-10-03 19:23:12',
|
||||
memo: '-',
|
||||
},
|
||||
];
|
||||
|
||||
export const PROFILES = {
|
||||
'GET /profile/progress': basicProgress,
|
||||
'GET /profile/goods': basicGoods,
|
||||
'GET /profile/advanced': {
|
||||
advancedOperation1,
|
||||
advancedOperation2,
|
||||
advancedOperation3,
|
||||
},
|
||||
};
|
||||
73
_mock/_role.ts
Normal file
73
_mock/_role.ts
Normal file
@ -0,0 +1,73 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { deepCopy } from '@delon/util';
|
||||
|
||||
interface Permission {
|
||||
id: number;
|
||||
parent_id: number;
|
||||
text: string;
|
||||
permission: number[];
|
||||
}
|
||||
|
||||
export const RuleData: Permission[] = [
|
||||
{ id: 1, parent_id: 0, text: '管理', permission: [1] },
|
||||
{ id: 2, parent_id: 0, text: '仓储', permission: [] },
|
||||
{ id: 3, parent_id: 0, text: '营销', permission: [] },
|
||||
{ id: 4, parent_id: 0, text: '第三方', permission: [7] },
|
||||
{
|
||||
id: 5,
|
||||
parent_id: 2,
|
||||
text: '仓储经理',
|
||||
permission: [6, 7, 8, 9, 10, 11, 12],
|
||||
},
|
||||
{ id: 6, parent_id: 2, text: '出库员', permission: [6, 7, 9, 10, 11, 12] },
|
||||
{ id: 7, parent_id: 2, text: '入库员', permission: [6, 7] },
|
||||
{ id: 8, parent_id: 3, text: '市场经理', permission: [6, 7] },
|
||||
{ id: 9, parent_id: 3, text: '销售人员', permission: [6, 7] },
|
||||
];
|
||||
|
||||
function get(params: any): any {
|
||||
let ret = deepCopy(RuleData);
|
||||
if (params.q) {
|
||||
ret = ret.filter((data: any) => data.text.indexOf(params.q) > -1);
|
||||
}
|
||||
const p = +(params.permission || '0');
|
||||
if (p > 0) {
|
||||
ret = ret.filter((data: any) => data.permission.includes(p));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getIdx(id: number): number {
|
||||
id = +id;
|
||||
const idx = RuleData.findIndex((w) => w.id === id);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
export const ROLES_PRO = {
|
||||
'/role': (req: MockRequest) => get(req.queryString),
|
||||
'POST /role': (req: MockRequest) => {
|
||||
const id = req.body.id || 0;
|
||||
if (id > 0) {
|
||||
const idx = getIdx(id);
|
||||
RuleData[idx] = { ...RuleData[idx], ...req.body };
|
||||
return { msg: 'ok', item: RuleData[idx] };
|
||||
}
|
||||
|
||||
const item = { ...req.body, id: RuleData.sort((a, b) => b.id - a.id)[0].id + 1 };
|
||||
RuleData.push(item);
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'DELETE /role/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
RuleData.splice(idx, 1);
|
||||
return { msg: 'ok' };
|
||||
},
|
||||
'POST /role/move': (req: MockRequest) => {
|
||||
const idx = getIdx(req.body.from || 0);
|
||||
RuleData[idx].parent_id = req.body.to || 0;
|
||||
return { msg: 'ok', item: RuleData[idx] };
|
||||
},
|
||||
};
|
||||
82
_mock/_rule.ts
Normal file
82
_mock/_rule.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import { HttpRequest } from '@angular/common/http';
|
||||
import { MockRequest } from '@delon/mock';
|
||||
|
||||
const list: any[] = [];
|
||||
|
||||
for (let i = 0; i < 46; i += 1) {
|
||||
list.push({
|
||||
key: i,
|
||||
disabled: i % 6 === 0,
|
||||
href: 'https://ant.design',
|
||||
avatar: [
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
|
||||
][i % 2],
|
||||
no: `TradeCode ${i}`,
|
||||
title: `一个任务名称 ${i}`,
|
||||
owner: '曲丽丽',
|
||||
description: '这是一段描述',
|
||||
callNo: Math.floor(Math.random() * 1000),
|
||||
status: Math.floor(Math.random() * 10) % 4,
|
||||
updatedAt: new Date(`2017-07-${i < 18 ? '0' + (Math.floor(i / 2) + 1) : Math.floor(i / 2) + 1}`),
|
||||
createdAt: new Date(`2017-07-${i < 18 ? '0' + (Math.floor(i / 2) + 1) : Math.floor(i / 2) + 1}`),
|
||||
progress: Math.ceil(Math.random() * 100),
|
||||
});
|
||||
}
|
||||
|
||||
function getRule(params: any): any[] {
|
||||
let ret = [...list];
|
||||
if (params.sorter) {
|
||||
const s = params.sorter.split('_');
|
||||
ret = ret.sort((prev, next) => {
|
||||
if (s[1] === 'descend') {
|
||||
return next[s[0]] - prev[s[0]];
|
||||
}
|
||||
return prev[s[0]] - next[s[0]];
|
||||
});
|
||||
}
|
||||
if (params.statusList && params.statusList.length > 0) {
|
||||
ret = ret.filter((data) => params.statusList.indexOf(data.status) > -1);
|
||||
}
|
||||
if (params.no) {
|
||||
ret = ret.filter((data) => data.no.indexOf(params.no) > -1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function removeRule(nos: string): boolean {
|
||||
nos.split(',').forEach((no) => {
|
||||
const idx = list.findIndex((w) => w.no === no);
|
||||
if (idx !== -1) {
|
||||
list.splice(idx, 1);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
function saveRule(description: string): void {
|
||||
const i = Math.ceil(Math.random() * 10000);
|
||||
list.unshift({
|
||||
key: i,
|
||||
href: 'https://ant.design',
|
||||
avatar: [
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
|
||||
][i % 2],
|
||||
no: `TradeCode ${i}`,
|
||||
title: `一个任务名称 ${i}`,
|
||||
owner: '曲丽丽',
|
||||
description,
|
||||
callNo: Math.floor(Math.random() * 1000),
|
||||
status: Math.floor(Math.random() * 10) % 2,
|
||||
updatedAt: new Date(),
|
||||
createdAt: new Date(),
|
||||
progress: Math.ceil(Math.random() * 100),
|
||||
});
|
||||
}
|
||||
|
||||
export const RULES = {
|
||||
'/rule': (req: MockRequest) => getRule(req.queryString),
|
||||
'DELETE /rule': (req: MockRequest) => removeRule(req.queryString.nos),
|
||||
'POST /rule': (req: MockRequest) => saveRule(req.body.description),
|
||||
};
|
||||
172
_mock/_trade.ts
Normal file
172
_mock/_trade.ts
Normal file
@ -0,0 +1,172 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { deepCopy } from '@delon/util';
|
||||
import { Random } from 'mockjs';
|
||||
|
||||
import { genMp, genName } from './utils';
|
||||
|
||||
interface Trade {
|
||||
id: number;
|
||||
buyer_id: number;
|
||||
buyer_nick: string;
|
||||
price: number;
|
||||
discount_fee: number;
|
||||
post_fee: number;
|
||||
payment: number;
|
||||
pay_time?: Date;
|
||||
status: number;
|
||||
status_str: string;
|
||||
logistics_name?: string;
|
||||
logistics_no?: string;
|
||||
finished?: Date;
|
||||
created: Date;
|
||||
wares: TradeWare[];
|
||||
memo?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface TradeWare {
|
||||
ware_id: number;
|
||||
sku_id: number;
|
||||
num: number;
|
||||
price: number;
|
||||
mp: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const DATA: Trade[] = [];
|
||||
const STATUS: { [key: string]: string } = {
|
||||
CANCELED: '取消',
|
||||
WAIT_BUYER_PAY: '等待买家付款',
|
||||
WAIT_PAY_CONFIRM: '支付确认中',
|
||||
WAIT_SELLER_STOCK_OUT: '等待出库',
|
||||
WAIT_GOODS_RECEIVE_CONFIRM: '等待确认收货',
|
||||
FINISHED: '交易成功'
|
||||
};
|
||||
|
||||
for (let i = 1; i <= 30; i += 1) {
|
||||
const buyer_nick = genName();
|
||||
const status: any = Object.keys(STATUS)[Random.natural(0, 5)];
|
||||
let pay_time: Date | null = null;
|
||||
let finished: Date | null = null;
|
||||
if (status !== 'WAIT_BUYER_PAY' || status !== 'CANCELED') {
|
||||
pay_time = new Date();
|
||||
}
|
||||
if (status !== 'FINISHED') {
|
||||
finished = new Date();
|
||||
}
|
||||
const price = Random.natural(100, 10000);
|
||||
const discount_fee = Random.natural(0, 100);
|
||||
const post_fee = Random.natural(6, 20);
|
||||
|
||||
DATA.push({
|
||||
id: 10000 * i,
|
||||
buyer_id: Random.natural(10000, 100000),
|
||||
buyer_nick,
|
||||
buyer_tel: Random.natural(10000000000, 19999999999),
|
||||
buyer_adr: Random.city(true),
|
||||
buyer_message: Random.title(5, 20),
|
||||
price,
|
||||
discount_fee,
|
||||
post_fee,
|
||||
payment: price - discount_fee + post_fee,
|
||||
pay_time,
|
||||
finished,
|
||||
status,
|
||||
status_str: STATUS[status],
|
||||
logistics_name: '',
|
||||
logistics_no: '',
|
||||
created: new Date(),
|
||||
wares: genWare(Random.natural(1, 5))
|
||||
} as any);
|
||||
}
|
||||
|
||||
function genWare(count: number): TradeWare[] {
|
||||
return new Array(count).fill({}).map((v, idx) => ({
|
||||
ware_id: Random.natural(10000, 10020),
|
||||
sku_id: (idx + 1) * 1000,
|
||||
num: Random.natural(1, 10),
|
||||
price: Random.natural(10, 500),
|
||||
mp: genMp(),
|
||||
title: Random.ctitle(5, 10)
|
||||
}));
|
||||
}
|
||||
|
||||
function get(params: any): any {
|
||||
let ret = deepCopy(DATA);
|
||||
if (params.sorter) {
|
||||
const s = params.sorter.split('_');
|
||||
ret = ret.sort((prev: any, next: any) => {
|
||||
if (s[1] === 'descend') {
|
||||
return next[s[0]] - prev[s[0]];
|
||||
}
|
||||
return prev[s[0]] - next[s[0]];
|
||||
});
|
||||
}
|
||||
if (params.id) {
|
||||
ret = ret.filter((data: any) => data.id == params.id);
|
||||
}
|
||||
if (params.statusList && params.statusList.length > 0) {
|
||||
ret = ret.filter((data: any) => params.statusList.indexOf(data.status) > -1);
|
||||
}
|
||||
if (params.ware_id) {
|
||||
ret = ret.filter((data: any) => data.wares.find((w: any) => w.ware_id == params.ware_id));
|
||||
}
|
||||
if (params.buyer_nick) {
|
||||
ret = ret.filter((data: any) => data.buyer_nick.indexOf(params.buyer_nick) > -1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getIdx(id: number): number {
|
||||
id = +id;
|
||||
const idx = DATA.findIndex(w => w.id === id);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
export const TRADES = {
|
||||
'/trade': (req: MockRequest) => {
|
||||
const pi = +(req.queryString.pi || 1);
|
||||
const ps = +(req.queryString.ps || 10);
|
||||
const data = get(req.queryString);
|
||||
return {
|
||||
total: data.length,
|
||||
list: data.slice((pi - 1) * ps, pi * ps)
|
||||
};
|
||||
},
|
||||
'POST /trade': (req: MockRequest) => {
|
||||
const id = req.body.id || 0;
|
||||
if (id > 0) {
|
||||
const idx = getIdx(id);
|
||||
DATA[idx] = { ...DATA[idx], ...req.body };
|
||||
return { msg: 'ok', item: DATA[idx] };
|
||||
}
|
||||
|
||||
const item = { ...req.body, id: DATA.sort((a, b) => b.id - a.id)[0].id + 1 };
|
||||
DATA.push(item);
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'/trade/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
const item = { ...DATA[idx] };
|
||||
return item;
|
||||
},
|
||||
'DELETE /trade/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
DATA.splice(idx, 1);
|
||||
return { msg: 'ok' };
|
||||
},
|
||||
'POST /trade/status': (req: MockRequest) => {
|
||||
const idx = getIdx(req.body.id || 0);
|
||||
DATA[idx].status = req.body.status;
|
||||
DATA[idx].status_str = STATUS[req.body.status];
|
||||
return { msg: 'ok', item: DATA[idx] };
|
||||
},
|
||||
'POST /trade/memo': (req: MockRequest) => {
|
||||
const idx = getIdx(req.body.id || 0);
|
||||
DATA[idx].memo = req.body.memo;
|
||||
return { msg: 'ok', item: DATA[idx] };
|
||||
}
|
||||
};
|
||||
91
_mock/_user-pro.ts
Normal file
91
_mock/_user-pro.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { deepCopy } from '@delon/util';
|
||||
import { Random } from 'mockjs';
|
||||
import { genName } from './utils';
|
||||
import { RuleData } from './_role';
|
||||
|
||||
interface UserPro {
|
||||
id: number;
|
||||
name: string;
|
||||
userName: string;
|
||||
email: string;
|
||||
verified: boolean;
|
||||
status: 'active' | 'banned' | 'deleted';
|
||||
role?: any;
|
||||
permission?: any[];
|
||||
created: Date;
|
||||
}
|
||||
|
||||
const DATA: UserPro[] = [];
|
||||
|
||||
for (let i = 1; i <= 20; i += 1) {
|
||||
const name = genName();
|
||||
DATA.push({
|
||||
id: i,
|
||||
name,
|
||||
userName: `user name ${i}`,
|
||||
email: `${name}` + ['@qq.com', '@gmail.com', '@163.com'][Math.floor(Math.random() * 10) % 3],
|
||||
verified: [true, false][Math.floor(Math.random() * 10) % 2],
|
||||
status: ['active', 'banned', 'deleted'][Math.floor(Math.random() * 10) % 3] as any,
|
||||
role: deepCopy(RuleData[Random.natural(0, RuleData.length - 1)]),
|
||||
permission: [],
|
||||
created: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
function get(params: any): any {
|
||||
let ret = deepCopy(DATA);
|
||||
if (params.q) {
|
||||
ret = ret.filter((data: any) => data.name.indexOf(params.q) > -1);
|
||||
}
|
||||
if (params.email) {
|
||||
ret = ret.filter((data: any) => data.email.indexOf(params.email) > -1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getIdx(id: number): number {
|
||||
id = +id;
|
||||
const idx = DATA.findIndex((w) => w.id === id);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
export const USERS_PRO = {
|
||||
'/user-pro': (req: MockRequest) => {
|
||||
const pi = +(req.queryString.pi || 1);
|
||||
const ps = +(req.queryString.ps || 10);
|
||||
const data = get(req.queryString);
|
||||
return {
|
||||
total: data.length,
|
||||
list: data.slice((pi - 1) * ps, pi * ps),
|
||||
};
|
||||
},
|
||||
'POST /user-pro': (req: MockRequest) => {
|
||||
const id = req.body.id || 0;
|
||||
// fix role data
|
||||
req.body.role = RuleData.find((w) => w.id === req.body.role.id);
|
||||
|
||||
if (id > 0) {
|
||||
const idx = getIdx(id);
|
||||
DATA[idx] = { ...DATA[idx], ...req.body };
|
||||
return { msg: 'ok', item: DATA[idx] };
|
||||
}
|
||||
|
||||
const item = { ...req.body, id: DATA.sort((a, b) => b.id - a.id)[0].id + 1 };
|
||||
DATA.push(item);
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'/user-pro/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
const item = { ...DATA[idx], ...req.body };
|
||||
return item;
|
||||
},
|
||||
'DELETE /user-pro/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
DATA.splice(idx, 1);
|
||||
return { msg: 'ok' };
|
||||
},
|
||||
};
|
||||
122
_mock/_user.ts
Normal file
122
_mock/_user.ts
Normal file
@ -0,0 +1,122 @@
|
||||
import { MockRequest } from '@delon/mock';
|
||||
|
||||
const list: any[] = [];
|
||||
const total = 50;
|
||||
|
||||
for (let i = 0; i < total; i += 1) {
|
||||
list.push({
|
||||
id: i + 1,
|
||||
disabled: i % 6 === 0,
|
||||
href: 'https://ant.design',
|
||||
avatar: [
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
|
||||
][i % 2],
|
||||
no: `TradeCode ${i}`,
|
||||
title: `一个任务名称 ${i}`,
|
||||
owner: '曲丽丽',
|
||||
description: '这是一段描述',
|
||||
callNo: Math.floor(Math.random() * 1000),
|
||||
status: Math.floor(Math.random() * 10) % 4,
|
||||
updatedAt: new Date(`2017-07-${Math.floor(i / 2) + 1}`),
|
||||
createdAt: new Date(`2017-07-${Math.floor(i / 2) + 1}`),
|
||||
progress: Math.ceil(Math.random() * 100),
|
||||
});
|
||||
}
|
||||
|
||||
function genData(params: any): { total: number; list: any[] } {
|
||||
let ret = [...list];
|
||||
const pi = +params.pi;
|
||||
const ps = +params.ps;
|
||||
const start = (pi - 1) * ps;
|
||||
|
||||
if (params.no) {
|
||||
ret = ret.filter((data) => data.no.indexOf(params.no) > -1);
|
||||
}
|
||||
|
||||
return { total: ret.length, list: ret.slice(start, ps * pi) };
|
||||
}
|
||||
|
||||
function saveData(id: number, value: any): { msg: string } {
|
||||
const item = list.find((w) => w.id === id);
|
||||
if (!item) {
|
||||
return { msg: '无效用户信息' };
|
||||
}
|
||||
Object.assign(item, value);
|
||||
return { msg: 'ok' };
|
||||
}
|
||||
|
||||
export const USERS = {
|
||||
'/user': (req: MockRequest) => genData(req.queryString),
|
||||
'/user/:id': (req: MockRequest) => list.find((w) => w.id === +req.params.id),
|
||||
'POST /user/:id': (req: MockRequest) => saveData(+req.params.id, req.body),
|
||||
'/user/current': {
|
||||
name: 'Cipchk',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
|
||||
userid: '00000001',
|
||||
email: 'cipchk@qq.com',
|
||||
signature: '海纳百川,有容乃大',
|
||||
title: '交互专家',
|
||||
group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED',
|
||||
tags: [
|
||||
{
|
||||
key: '0',
|
||||
label: '很有想法的',
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
label: '专注撩妹',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: '帅~',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: '通吃',
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
label: '专职后端',
|
||||
},
|
||||
{
|
||||
key: '5',
|
||||
label: '海纳百川',
|
||||
},
|
||||
],
|
||||
notifyCount: 12,
|
||||
country: 'China',
|
||||
geographic: {
|
||||
province: {
|
||||
label: '上海',
|
||||
key: '330000',
|
||||
},
|
||||
city: {
|
||||
label: '市辖区',
|
||||
key: '330100',
|
||||
},
|
||||
},
|
||||
address: 'XX区XXX路 XX 号',
|
||||
phone: '你猜-你猜你猜猜猜',
|
||||
},
|
||||
'POST /user/avatar': 'ok',
|
||||
'POST /login/account': (req: MockRequest) => {
|
||||
const data = req.body;
|
||||
if (!(data.userName === 'admin' || data.userName === 'user') || data.password !== 'ng-alain.com') {
|
||||
return { msg: `Invalid username or password(admin/ng-alain.com)` };
|
||||
}
|
||||
return {
|
||||
msg: 'ok',
|
||||
user: {
|
||||
token: '123456789',
|
||||
name: data.userName,
|
||||
email: `${data.userName}@qq.com`,
|
||||
id: 10000,
|
||||
time: +new Date(),
|
||||
},
|
||||
};
|
||||
},
|
||||
'POST /register': {
|
||||
msg: 'ok',
|
||||
},
|
||||
};
|
||||
163
_mock/_ware.ts
Normal file
163
_mock/_ware.ts
Normal file
@ -0,0 +1,163 @@
|
||||
import { MockRequest, MockStatusError } from '@delon/mock';
|
||||
import { deepCopy } from '@delon/util';
|
||||
import { genMp } from './utils';
|
||||
|
||||
interface UserPro {
|
||||
cid: number;
|
||||
cname: string;
|
||||
id: number;
|
||||
name: string;
|
||||
mp: string;
|
||||
stock: number;
|
||||
outer_id: string;
|
||||
market_price: number;
|
||||
price: number;
|
||||
sale_num: number;
|
||||
status: string;
|
||||
modified: Date;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const DATA: UserPro[] = [];
|
||||
|
||||
for (let i = 1; i <= 20; i += 1) {
|
||||
const name = ['HUAWEI Mate 20 Pro', '小米MAX3', 'IPhone X', 'Gree 8,000 BTU Portable Air Conditioner'][
|
||||
Math.floor(Math.random() * 10) % 4
|
||||
];
|
||||
DATA.push({
|
||||
cid: i * 1000,
|
||||
cname: '',
|
||||
id: i + 10000,
|
||||
name,
|
||||
mp: genMp(),
|
||||
stock: Math.floor(Math.random() * 1000) % 1000,
|
||||
outer_id: `S50-${Math.floor(Math.random() * 100) % 100}`,
|
||||
market_price: Math.floor(Math.random() * 1000) % 1000,
|
||||
price: Math.floor(Math.random() * 1000) % 1000,
|
||||
sale_num: Math.floor(Math.random() * 200) % 200,
|
||||
modified: new Date(),
|
||||
status: ['CUSTORMER_DOWN', 'ON_SALE', 'AUDIT_AWAIT', 'DELETED'][Math.floor(Math.random() * 10) % 4],
|
||||
brand: 1,
|
||||
place: 1,
|
||||
});
|
||||
}
|
||||
|
||||
function get(params: any): any {
|
||||
let ret = deepCopy(DATA);
|
||||
if (params.q) {
|
||||
ret = ret.filter((data: any) => data.name.indexOf(params.q) > -1);
|
||||
}
|
||||
if (params.email) {
|
||||
ret = ret.filter((data: any) => data.email.indexOf(params.email) > -1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getIdx(id: number): number {
|
||||
id = +id;
|
||||
const idx = DATA.findIndex((w) => w.id === id);
|
||||
if (idx === -1) {
|
||||
throw new MockStatusError(404);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
export const WARES = {
|
||||
'/ware': (req: MockRequest) => {
|
||||
const pi = +(req.queryString.pi || 1);
|
||||
const ps = +(req.queryString.ps || 10);
|
||||
const data = get(req.queryString);
|
||||
return {
|
||||
total: data.length,
|
||||
list: data.slice((pi - 1) * ps, pi * ps),
|
||||
};
|
||||
},
|
||||
'POST /ware': (req: MockRequest) => {
|
||||
const id = req.body.id || 0;
|
||||
if (id > 0) {
|
||||
const idx = getIdx(id);
|
||||
DATA[idx] = { ...DATA[idx], ...req.body };
|
||||
return { msg: 'ok', item: DATA[idx] };
|
||||
}
|
||||
|
||||
const item = { ...req.body, id: DATA.sort((a, b) => b.id - a.id)[0].id + 1 };
|
||||
DATA.push(item);
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'/ware/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
const item = {
|
||||
id: 0,
|
||||
brand: 1,
|
||||
is_7return: true,
|
||||
prop: {
|
||||
1: '是',
|
||||
2: '24天',
|
||||
3: '0.5克',
|
||||
},
|
||||
place: 1,
|
||||
weight: 10,
|
||||
skus: [
|
||||
{
|
||||
id: 10001,
|
||||
attributes: '1:10',
|
||||
names: [`红色`, `S`],
|
||||
price: 1000,
|
||||
stock: 10,
|
||||
},
|
||||
{
|
||||
id: 10002,
|
||||
attributes: '1:11',
|
||||
names: [`红色`, `M`],
|
||||
price: 1000,
|
||||
stock: 11,
|
||||
},
|
||||
{
|
||||
id: 10003,
|
||||
attributes: '3:10',
|
||||
names: [`蓝色1`, `S`],
|
||||
price: 1000,
|
||||
stock: 12,
|
||||
},
|
||||
{
|
||||
id: 10004,
|
||||
attributes: '3:11',
|
||||
names: [`蓝色1`, `M`],
|
||||
price: 1000,
|
||||
stock: 13,
|
||||
},
|
||||
],
|
||||
imgs: {
|
||||
0: ['https://randomuser.me/api/portraits/lego/0.jpg'],
|
||||
1: ['https://randomuser.me/api/portraits/lego/1.jpg'],
|
||||
3: ['https://randomuser.me/api/portraits/lego/3.jpg'],
|
||||
},
|
||||
desc: `<p>Test</p>`,
|
||||
...(DATA[idx] as any),
|
||||
};
|
||||
return item;
|
||||
},
|
||||
'DELETE /ware/:id': (req: MockRequest) => {
|
||||
const idx = getIdx(req.params.id || 0);
|
||||
DATA.splice(idx, 1);
|
||||
return { msg: 'ok' };
|
||||
},
|
||||
'POST /ware/status': (req: MockRequest) => {
|
||||
const idx = getIdx(req.body.id || 0);
|
||||
const item = DATA[idx];
|
||||
item.status = req.body.status;
|
||||
return { msg: 'ok', item };
|
||||
},
|
||||
'/ware/cat': [
|
||||
{ id: 1, name: '颜色', value: '红色', color: '#f5222d', type: 'color' },
|
||||
{ id: 2, name: '颜色', value: '绿色', color: '#a0d911', type: 'color' },
|
||||
{ id: 3, name: '颜色', value: '蓝色', color: '#1890ff', type: 'color' },
|
||||
{ id: 4, name: '颜色', value: '洋红', color: '#eb2f96', type: 'color' },
|
||||
{ id: 10, name: '尺寸', value: 'S', type: 'size' },
|
||||
{ id: 11, name: '尺寸', value: 'M', type: 'size' },
|
||||
{ id: 12, name: '尺寸', value: 'L', type: 'size' },
|
||||
{ id: 13, name: '尺寸', value: 'XL', type: 'size' },
|
||||
{ id: 14, name: '尺寸', value: 'XXL', type: 'size' },
|
||||
{ id: 15, name: '尺寸', value: 'XXXL', type: 'size' },
|
||||
],
|
||||
};
|
||||
21
_mock/index.ts
Normal file
21
_mock/index.ts
Normal file
@ -0,0 +1,21 @@
|
||||
export * from './_profile';
|
||||
export * from './_rule';
|
||||
export * from './_api';
|
||||
export * from './_chart';
|
||||
export * from './_pois';
|
||||
export * from './_user';
|
||||
export * from './_geo';
|
||||
|
||||
export * from './_file-manager';
|
||||
export * from './_img';
|
||||
export * from './_log';
|
||||
export * from './_menu';
|
||||
export * from './_permission';
|
||||
export * from './_role';
|
||||
export * from './_user-pro';
|
||||
export * from './utils';
|
||||
|
||||
export * from './_forum';
|
||||
export * from './_other';
|
||||
export * from './_trade';
|
||||
export * from './_ware';
|
||||
160
_mock/utils.ts
Normal file
160
_mock/utils.ts
Normal file
@ -0,0 +1,160 @@
|
||||
import addDays from 'date-fns/addDays';
|
||||
import format from 'date-fns/format';
|
||||
import { Random } from 'mockjs';
|
||||
|
||||
export const COLOR_NAMES = ['red', 'volcano', 'orange', 'gold', 'yellow', 'lime', 'green', 'cyan', 'blue', 'geekblue', 'purple', 'magenta'];
|
||||
|
||||
export function genName(): any {
|
||||
return genArr(['asdf', 'cipchk', '卡色']);
|
||||
}
|
||||
|
||||
export function genProvince(): any {
|
||||
return genArr([
|
||||
'台湾',
|
||||
'河北',
|
||||
'山西',
|
||||
'内蒙古',
|
||||
'辽宁',
|
||||
'吉林',
|
||||
'黑龙江',
|
||||
'江苏',
|
||||
'浙江',
|
||||
'安徽',
|
||||
'福建',
|
||||
'江西',
|
||||
'山东',
|
||||
'河南',
|
||||
'湖北',
|
||||
'湖南',
|
||||
'广东',
|
||||
'广西',
|
||||
'海南',
|
||||
'四川',
|
||||
'贵州',
|
||||
'云南',
|
||||
'西藏',
|
||||
'陕西',
|
||||
'甘肃',
|
||||
'青海',
|
||||
'宁夏',
|
||||
'新疆',
|
||||
'北京',
|
||||
'天津',
|
||||
'上海',
|
||||
'重庆',
|
||||
'香港',
|
||||
'澳门',
|
||||
]);
|
||||
}
|
||||
|
||||
export function genArr(arr: any[], count: number = 1): any {
|
||||
if (count === 1) {
|
||||
return arr[Random.natural(0, arr.length - 1)];
|
||||
}
|
||||
return new Array(count <= -1 ? Random.natural(0, -count) : count).fill({}).map(() => {
|
||||
return arr[Random.natural(0, arr.length - 1)];
|
||||
});
|
||||
}
|
||||
|
||||
export function genColorName(): any {
|
||||
return genArr(COLOR_NAMES);
|
||||
}
|
||||
|
||||
export function genLabel(): any {
|
||||
return genArr([
|
||||
{
|
||||
color: 'green',
|
||||
text: 'Clients',
|
||||
},
|
||||
{
|
||||
color: 'red',
|
||||
text: 'Important',
|
||||
},
|
||||
{
|
||||
color: 'blue',
|
||||
text: 'Other',
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
/** 生成头像,`id` 只能0-8 */
|
||||
export function genMp(id?: number): string {
|
||||
return `https://randomuser.me/api/portraits/lego/${typeof id === 'undefined' ? Random.natural(0, 8) : id}.jpg`;
|
||||
}
|
||||
|
||||
export function genBigMp(): string {
|
||||
return `./assets/tmp/img-big/${Random.natural(1, 8)}.jpg`;
|
||||
}
|
||||
|
||||
export function genTag(num: number = -3): any {
|
||||
return genArr(['Angular', 'Node', 'HTML5', 'Less', 'Db', 'Python', 'Go'], num);
|
||||
}
|
||||
|
||||
export function addDate(days: number): Date {
|
||||
return addDays(new Date(), days);
|
||||
}
|
||||
|
||||
export function genData(days: number, dateFormat: string = 'yyyy-MM-dd'): string {
|
||||
return format(addDate(days), dateFormat);
|
||||
}
|
||||
|
||||
export function rudeCopy(obj: any): string {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
export function genContent(): string {
|
||||
return `
|
||||
<h2>主标题</h2>
|
||||
<h3>次标题</h3>
|
||||
<p><a>段落</a>,${Random.cparagraph(1, 1)}<p>
|
||||
<p>段落,${Random.paragraph(1, 1)}<p>
|
||||
<h2>列表</h2>
|
||||
<ol>
|
||||
<li>
|
||||
<p>段落,${Random.paragraph(1, 1)}<p>
|
||||
<ul>
|
||||
<li><a>${Random.ctitle(5, 10)}</a></li>
|
||||
<li><a>${Random.ctitle(5, 10)}</a></li>
|
||||
<li><a>${Random.ctitle(5, 10)}</a></li>
|
||||
<li><a>${Random.ctitle(5, 10)}</a></li>
|
||||
<li><a>${Random.ctitle(5, 10)}</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>段落,${Random.paragraph(1, 1)}<p>
|
||||
</li>
|
||||
<li>
|
||||
<p>段落,${Random.paragraph(1, 1)}<p>
|
||||
</li>
|
||||
</ol>
|
||||
<h2>图像</h2>
|
||||
<p><img src="${Random.image()}"></p>
|
||||
<h2>表格</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>列</th>
|
||||
<th>列</th>
|
||||
<th>列</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>列</td>
|
||||
<td>列</td>
|
||||
<td>列</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>列</td>
|
||||
<td>列</td>
|
||||
<td>列</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>列</td>
|
||||
<td>列</td>
|
||||
<td>列</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
Reference in New Issue
Block a user