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 `
${new Array(Random.natural(1, 3)) .fill('') .map(v => Random.sentence()) .join('
')}
`; } 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) };