diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts index ca868c3..d527406 100644 --- a/src/app/app.routing.ts +++ b/src/app/app.routing.ts @@ -260,6 +260,20 @@ export const appRoutes: Route[] = [ (m: any) => m.WithdrawModule ), }, + { + path: 'web-calculate', + loadChildren: () => + import( + 'app/modules/admin/bank/web-calculate/web-calculate.module' + ).then((m: any) => m.WebCalculateModule), + }, + { + path: 'partner-calculate', + loadChildren: () => + import( + 'app/modules/admin/bank/partner-calculate/partner-calculate.module' + ).then((m: any) => m.PartnerCalculateModule), + }, ], }, { @@ -469,6 +483,20 @@ export const appRoutes: Route[] = [ (m: any) => m.PopupModule ), }, + { + path: 'message', + loadChildren: () => + import('app/modules/admin/board/message/message.module').then( + (m: any) => m.MessageModule + ), + }, + { + path: 'service', + loadChildren: () => + import('app/modules/admin/board/service/service.module').then( + (m: any) => m.ServiceModule + ), + }, ], }, ], diff --git a/src/app/mock-api/apps/bank/partner-calculate/api.ts b/src/app/mock-api/apps/bank/partner-calculate/api.ts new file mode 100644 index 0000000..400d033 --- /dev/null +++ b/src/app/mock-api/apps/bank/partner-calculate/api.ts @@ -0,0 +1,222 @@ +import { Injectable } from '@angular/core'; +import { assign, cloneDeep } from 'lodash-es'; +import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api'; +import { partnerCalculates as partnerCalculatesData } from './data'; + +@Injectable({ + providedIn: 'root', +}) +export class BankPartnerCalculateMockApi { + private _partnerCalculates: any[] = partnerCalculatesData; + + /** + * Constructor + */ + constructor(private _fuseMockApiService: FuseMockApiService) { + // Register Mock API handlers + this.registerHandlers(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Register Mock API handlers + */ + registerHandlers(): void { + // ----------------------------------------------------------------------------------------------------- + // @ PartnerCalculates - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/bank/partner-calculate/partner-calculates', 300) + .reply(({ request }) => { + // Get available queries + const search = request.params.get('search'); + const sort = request.params.get('sort') || 'name'; + const order = request.params.get('order') || 'asc'; + const page = parseInt(request.params.get('page') ?? '1', 10); + const size = parseInt(request.params.get('size') ?? '10', 10); + + // Clone the partnerCalculates + let partnerCalculates: any[] | null = cloneDeep( + this._partnerCalculates + ); + + // Sort the partnerCalculates + if (sort === 'sku' || sort === 'name' || sort === 'active') { + partnerCalculates.sort((a, b) => { + const fieldA = a[sort].toString().toUpperCase(); + const fieldB = b[sort].toString().toUpperCase(); + return order === 'asc' + ? fieldA.localeCompare(fieldB) + : fieldB.localeCompare(fieldA); + }); + } else { + partnerCalculates.sort((a, b) => + order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort] + ); + } + + // If search exists... + if (search) { + // Filter the partnerCalculates + partnerCalculates = partnerCalculates.filter( + (contact: any) => + contact.name && + contact.name.toLowerCase().includes(search.toLowerCase()) + ); + } + + // Paginate - Start + const partnerCalculatesLength = partnerCalculates.length; + + // Calculate pagination details + const begin = page * size; + const end = Math.min(size * (page + 1), partnerCalculatesLength); + const lastPage = Math.max(Math.ceil(partnerCalculatesLength / size), 1); + + // Prepare the pagination object + let pagination = {}; + + // If the requested page number is bigger than + // the last possible page number, return null for + // partnerCalculates but also send the last possible page so + // the app can navigate to there + if (page > lastPage) { + partnerCalculates = null; + pagination = { + lastPage, + }; + } else { + // Paginate the results by size + partnerCalculates = partnerCalculates.slice(begin, end); + + // Prepare the pagination mock-api + pagination = { + length: partnerCalculatesLength, + size: size, + page: page, + lastPage: lastPage, + startIndex: begin, + endIndex: end - 1, + }; + } + + // Return the response + return [ + 200, + { + partnerCalculates, + pagination, + }, + ]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ PartnerCalculate - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/bank/partner-calculate/partner-calculate') + .reply(({ request }) => { + // Get the id from the params + const id = request.params.get('id'); + + // Clone the partnerCalculates + const partnerCalculates = cloneDeep(this._partnerCalculates); + + // Find the partnerCalculate + const partnerCalculate = partnerCalculates.find( + (item: any) => item.id === id + ); + + // Return the response + return [200, partnerCalculate]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ PartnerCalculate - POST + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPost('api/apps/bank/partner-calculate/partner-calculate') + .reply(() => { + // Generate a new partnerCalculate + const newPartnerCalculate = { + id: FuseMockApiUtils.guid(), + rank: '', + level: '', + nickname: '', + paymentDue: '', + calculateType: '', + accountHolder: '', + note: '', + registrationDate: '', + processDate: '', + deposit: '', + withdrawal: '', + total: '', + gameMoney: '', + highRank: '', + state: '', + }; + + // Unshift the new partnerCalculate + this._partnerCalculates.unshift(newPartnerCalculate); + + // Return the response + return [200, newPartnerCalculate]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ PartnerCalculate - PATCH + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPatch('api/apps/bank/partner-calculate/partner-calculate') + .reply(({ request }) => { + // Get the id and partnerCalculate + const id = request.body.id; + const partnerCalculate = cloneDeep(request.body.partnerCalculate); + + // Prepare the updated partnerCalculate + let updatedPartnerCalculate = null; + + // Find the partnerCalculate and update it + this._partnerCalculates.forEach((item, index, partnerCalculates) => { + if (item.id === id) { + // Update the partnerCalculate + partnerCalculates[index] = assign( + {}, + partnerCalculates[index], + partnerCalculate + ); + + // Store the updated partnerCalculate + updatedPartnerCalculate = partnerCalculates[index]; + } + }); + + // Return the response + return [200, updatedPartnerCalculate]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ PartnerCalculate - DELETE + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onDelete('api/apps/bank/partner-calculate/partner-calculate') + .reply(({ request }) => { + // Get the id + const id = request.params.get('id'); + + // Find the partnerCalculate and delete it + this._partnerCalculates.forEach((item, index) => { + if (item.id === id) { + this._partnerCalculates.splice(index, 1); + } + }); + + // Return the response + return [200, true]; + }); + } +} diff --git a/src/app/mock-api/apps/bank/partner-calculate/data.ts b/src/app/mock-api/apps/bank/partner-calculate/data.ts new file mode 100644 index 0000000..6cfd839 --- /dev/null +++ b/src/app/mock-api/apps/bank/partner-calculate/data.ts @@ -0,0 +1,58 @@ +/* eslint-disable */ + +export const partnerCalculates = [ + { + rank: '회원', + level: 4, + id: 'aa100', + nickname: 'aa100', + paymentDue: 50000, + calculateType: '롤링', + accountHolder: '광주은행2sss', + note: '@', + registrationDate: '2022-06-18 13:14', + processDate: '000-0-0 0:0', + deposit: 41200000, + withdraw: 19000000, + total: 22200000, + gameMoney: 67131, + highRank: '[매장]kgon5', + state: '신청', + }, + { + rank: '회원', + level: 1, + id: 'onon6', + nickname: '가가가', + paymentDue: 100000, + calculateType: '롤링', + accountHolder: '가가가', + note: '', + registrationDate: '2022-06-13 12:57', + processDate: '2022-06-13 12:58', + deposit: 200000, + withdraw: 0, + total: 200000, + gameMoney: 0, + highRank: '[매장]on04', + state: '완료', + }, + { + rank: '회원', + level: 1, + id: 'onon6', + nickname: '가가가', + paymentDue: 100000, + calculateType: '롤링', + accountHolder: '가가가', + note: '', + registrationDate: '2022-06-13 12:56', + processDate: '2022-06-13 12:57', + deposit: 200000, + withdraw: 0, + total: 200000, + gameMoney: 0, + highRank: '[매장]on04', + state: '완료', + }, +]; diff --git a/src/app/mock-api/apps/bank/web-calculate/api.ts b/src/app/mock-api/apps/bank/web-calculate/api.ts new file mode 100644 index 0000000..e1375ab --- /dev/null +++ b/src/app/mock-api/apps/bank/web-calculate/api.ts @@ -0,0 +1,218 @@ +import { Injectable } from '@angular/core'; +import { assign, cloneDeep } from 'lodash-es'; +import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api'; +import { webCalculates as webCalculatesData } from './data'; + +@Injectable({ + providedIn: 'root', +}) +export class BankWebCalculateMockApi { + private _webCalculates: any[] = webCalculatesData; + + /** + * Constructor + */ + constructor(private _fuseMockApiService: FuseMockApiService) { + // Register Mock API handlers + this.registerHandlers(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Register Mock API handlers + */ + registerHandlers(): void { + // ----------------------------------------------------------------------------------------------------- + // @ WebCalculates - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/bank/web-calculate/web-calculates', 300) + .reply(({ request }) => { + // Get available queries + const search = request.params.get('search'); + const sort = request.params.get('sort') || 'name'; + const order = request.params.get('order') || 'asc'; + const page = parseInt(request.params.get('page') ?? '1', 10); + const size = parseInt(request.params.get('size') ?? '10', 10); + + // Clone the webCalculates + let webCalculates: any[] | null = cloneDeep(this._webCalculates); + + // Sort the webCalculates + if (sort === 'sku' || sort === 'name' || sort === 'active') { + webCalculates.sort((a, b) => { + const fieldA = a[sort].toString().toUpperCase(); + const fieldB = b[sort].toString().toUpperCase(); + return order === 'asc' + ? fieldA.localeCompare(fieldB) + : fieldB.localeCompare(fieldA); + }); + } else { + webCalculates.sort((a, b) => + order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort] + ); + } + + // If search exists... + if (search) { + // Filter the webCalculates + webCalculates = webCalculates.filter( + (contact: any) => + contact.name && + contact.name.toLowerCase().includes(search.toLowerCase()) + ); + } + + // Paginate - Start + const webCalculatesLength = webCalculates.length; + + // Calculate pagination details + const begin = page * size; + const end = Math.min(size * (page + 1), webCalculatesLength); + const lastPage = Math.max(Math.ceil(webCalculatesLength / size), 1); + + // Prepare the pagination object + let pagination = {}; + + // If the requested page number is bigger than + // the last possible page number, return null for + // webCalculates but also send the last possible page so + // the app can navigate to there + if (page > lastPage) { + webCalculates = null; + pagination = { + lastPage, + }; + } else { + // Paginate the results by size + webCalculates = webCalculates.slice(begin, end); + + // Prepare the pagination mock-api + pagination = { + length: webCalculatesLength, + size: size, + page: page, + lastPage: lastPage, + startIndex: begin, + endIndex: end - 1, + }; + } + + // Return the response + return [ + 200, + { + webCalculates, + pagination, + }, + ]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ WebCalculate - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/bank/web-calculate/web-calculate') + .reply(({ request }) => { + // Get the id from the params + const id = request.params.get('id'); + + // Clone the webCalculates + const webCalculates = cloneDeep(this._webCalculates); + + // Find the webCalculate + const webCalculate = webCalculates.find((item: any) => item.id === id); + + // Return the response + return [200, webCalculate]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ WebCalculate - POST + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPost('api/apps/bank/web-calculate/web-calculate') + .reply(() => { + // Generate a new webCalculate + const newWebCalculate = { + id: FuseMockApiUtils.guid(), + rank: '', + level: '', + nickname: '', + paymentDue: '', + calculateType: '', + accountHolder: '', + note: '', + registrationDate: '', + processDate: '', + deposit: '', + withdrawal: '', + total: '', + gameMoney: '', + highRank: '', + state: '', + }; + + // Unshift the new webCalculate + this._webCalculates.unshift(newWebCalculate); + + // Return the response + return [200, newWebCalculate]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ WebCalculate - PATCH + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPatch('api/apps/bank/web-calculate/web-calculate') + .reply(({ request }) => { + // Get the id and webCalculate + const id = request.body.id; + const webCalculate = cloneDeep(request.body.webCalculate); + + // Prepare the updated webCalculate + let updatedWebCalculate = null; + + // Find the webCalculate and update it + this._webCalculates.forEach((item, index, webCalculates) => { + if (item.id === id) { + // Update the webCalculate + webCalculates[index] = assign( + {}, + webCalculates[index], + webCalculate + ); + + // Store the updated webCalculate + updatedWebCalculate = webCalculates[index]; + } + }); + + // Return the response + return [200, updatedWebCalculate]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ WebCalculate - DELETE + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onDelete('api/apps/bank/web-calculate/web-calculate') + .reply(({ request }) => { + // Get the id + const id = request.params.get('id'); + + // Find the webCalculate and delete it + this._webCalculates.forEach((item, index) => { + if (item.id === id) { + this._webCalculates.splice(index, 1); + } + }); + + // Return the response + return [200, true]; + }); + } +} diff --git a/src/app/mock-api/apps/bank/web-calculate/data.ts b/src/app/mock-api/apps/bank/web-calculate/data.ts new file mode 100644 index 0000000..8e2642d --- /dev/null +++ b/src/app/mock-api/apps/bank/web-calculate/data.ts @@ -0,0 +1,58 @@ +/* eslint-disable */ + +export const webCalculates = [ + { + rank: '회원', + level: 4, + id: 'aa100', + nickname: 'aa100', + paymentDue: 50000, + calculateType: '롤링', + accountHolder: '광주은행2sss', + note: '@', + registrationDate: '2022-06-18 13:14', + processDate: '000-0-0 0:0', + deposit: 41200000, + withdraw: 19000000, + total: 22200000, + gameMoney: 67131, + highRank: '[매장]kgon5', + state: '신청', + }, + { + rank: '회원', + level: 1, + id: 'onon6', + nickname: '가가가', + paymentDue: 100000, + calculateType: '롤링', + accountHolder: '가가가', + note: '', + registrationDate: '2022-06-13 12:57', + processDate: '2022-06-13 12:58', + deposit: 200000, + withdraw: 0, + total: 200000, + gameMoney: 0, + highRank: '[매장]on04', + state: '완료', + }, + { + rank: '회원', + level: 1, + id: 'onon6', + nickname: '가가가', + paymentDue: 100000, + calculateType: '롤링', + accountHolder: '가가가', + note: '', + registrationDate: '2022-06-13 12:56', + processDate: '2022-06-13 12:57', + deposit: 200000, + withdraw: 0, + total: 200000, + gameMoney: 0, + highRank: '[매장]on04', + state: '완료', + }, +]; diff --git a/src/app/mock-api/apps/board/message/api.ts b/src/app/mock-api/apps/board/message/api.ts new file mode 100644 index 0000000..9419efe --- /dev/null +++ b/src/app/mock-api/apps/board/message/api.ts @@ -0,0 +1,217 @@ +import { Injectable } from '@angular/core'; +import { assign, cloneDeep } from 'lodash-es'; +import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api'; +import { messages as messagesData } from './data'; + +@Injectable({ + providedIn: 'root', +}) +export class BoardMessageMockApi { + private _messages: any[] = messagesData; + + /** + * Constructor + */ + constructor(private _fuseMockApiService: FuseMockApiService) { + // Register Mock API handlers + this.registerHandlers(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Register Mock API handlers + */ + registerHandlers(): void { + // ----------------------------------------------------------------------------------------------------- + // @ Messages - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/board/message/messages', 300) + .reply(({ request }) => { + // Get available queries + const search = request.params.get('search'); + const sort = request.params.get('sort') || 'name'; + const order = request.params.get('order') || 'asc'; + const page = parseInt(request.params.get('page') ?? '1', 10); + const size = parseInt(request.params.get('size') ?? '10', 10); + + // Clone the messages + let messages: any[] | null = cloneDeep(this._messages); + + // Sort the messages + if (sort === 'sku' || sort === 'name' || sort === 'active') { + messages.sort((a, b) => { + const fieldA = a[sort].toString().toUpperCase(); + const fieldB = b[sort].toString().toUpperCase(); + return order === 'asc' + ? fieldA.localeCompare(fieldB) + : fieldB.localeCompare(fieldA); + }); + } else { + messages.sort((a, b) => + order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort] + ); + } + + // If search exists... + if (search) { + // Filter the messages + messages = messages.filter( + (contact: any) => + contact.name && + contact.name.toLowerCase().includes(search.toLowerCase()) + ); + } + + // Paginate - Start + const messagesLength = messages.length; + + // Calculate pagination details + const begin = page * size; + const end = Math.min(size * (page + 1), messagesLength); + const lastPage = Math.max(Math.ceil(messagesLength / size), 1); + + // Prepare the pagination object + let pagination = {}; + + // If the requested page number is bigger than + // the last possible page number, return null for + // messages but also send the last possible page so + // the app can navigate to there + if (page > lastPage) { + messages = null; + pagination = { + lastPage, + }; + } else { + // Paginate the results by size + messages = messages.slice(begin, end); + + // Prepare the pagination mock-api + pagination = { + length: messagesLength, + size: size, + page: page, + lastPage: lastPage, + startIndex: begin, + endIndex: end - 1, + }; + } + + // Return the response + return [ + 200, + { + messages, + pagination, + }, + ]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ Message - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/board/message/message') + .reply(({ request }) => { + // Get the id from the params + const id = request.params.get('id'); + + // Clone the messages + const messages = cloneDeep(this._messages); + + // Find the message + const message = messages.find((item: any) => item.id === id); + + // Return the response + return [200, message]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ Message - POST + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPost('api/apps/board/message/message') + .reply(() => { + // Generate a new message + const newMessage = { + id: FuseMockApiUtils.guid(), + category: '', + name: 'A New User', + description: '', + tags: [], + sku: '', + barcode: '', + brand: '', + vendor: '', + stock: '', + reserved: '', + cost: '', + basePrice: '', + taxPercent: '', + price: '', + weight: '', + thumbnail: '', + images: [], + active: false, + }; + + // Unshift the new message + this._messages.unshift(newMessage); + + // Return the response + return [200, newMessage]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ Message - PATCH + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPatch('api/apps/board/message/message') + .reply(({ request }) => { + // Get the id and message + const id = request.body.id; + const message = cloneDeep(request.body.message); + + // Prepare the updated message + let updatedMessage = null; + + // Find the message and update it + this._messages.forEach((item, index, messages) => { + if (item.id === id) { + // Update the message + messages[index] = assign({}, messages[index], message); + + // Store the updated Message + updatedMessage = messages[index]; + } + }); + + // Return the response + return [200, updatedMessage]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ Message - DELETE + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onDelete('api/apps/board/message/message') + .reply(({ request }) => { + // Get the id + const id = request.params.get('id'); + + // Find the message and delete it + this._messages.forEach((item, index) => { + if (item.id === id) { + this._messages.splice(index, 1); + } + }); + + // Return the response + return [200, true]; + }); + } +} diff --git a/src/app/mock-api/apps/board/message/data.ts b/src/app/mock-api/apps/board/message/data.ts new file mode 100644 index 0000000..3b42aaa --- /dev/null +++ b/src/app/mock-api/apps/board/message/data.ts @@ -0,0 +1,33 @@ +/* eslint-disable */ + +export const messages = [ + { + id: 'on00', + totalPartnerCount: '5', + totalHoldingMoney: 303675, + totalComp: 108933, + total: 412608, + branchCount: 1, + divisionCount: 1, + officeCount: 1, + storeCount: 1, + memberCount: 1, + nickname: 'on00', + accountHolder: '11', + phoneNumber: '010-1111-1111', + calculateType: '롤링', + ownCash: 50000, + ownComp: 1711, + ownCoupon: 50000, + gameMoney: 0, + todayComp: 0, + totalDeposit: 0, + totalWithdraw: 0, + balance: 0, + registDate: '2022-06-12 15:38', + finalSigninDate: '', + ip: '', + state: '정상', + note: '', + }, +]; diff --git a/src/app/mock-api/apps/board/service/api.ts b/src/app/mock-api/apps/board/service/api.ts new file mode 100644 index 0000000..59b0f09 --- /dev/null +++ b/src/app/mock-api/apps/board/service/api.ts @@ -0,0 +1,217 @@ +import { Injectable } from '@angular/core'; +import { assign, cloneDeep } from 'lodash-es'; +import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api'; +import { services as servicesData } from './data'; + +@Injectable({ + providedIn: 'root', +}) +export class BoardServiceMockApi { + private _services: any[] = servicesData; + + /** + * Constructor + */ + constructor(private _fuseMockApiService: FuseMockApiService) { + // Register Mock API handlers + this.registerHandlers(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Register Mock API handlers + */ + registerHandlers(): void { + // ----------------------------------------------------------------------------------------------------- + // @ Services - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/board/service/services', 300) + .reply(({ request }) => { + // Get available queries + const search = request.params.get('search'); + const sort = request.params.get('sort') || 'name'; + const order = request.params.get('order') || 'asc'; + const page = parseInt(request.params.get('page') ?? '1', 10); + const size = parseInt(request.params.get('size') ?? '10', 10); + + // Clone the services + let services: any[] | null = cloneDeep(this._services); + + // Sort the services + if (sort === 'sku' || sort === 'name' || sort === 'active') { + services.sort((a, b) => { + const fieldA = a[sort].toString().toUpperCase(); + const fieldB = b[sort].toString().toUpperCase(); + return order === 'asc' + ? fieldA.localeCompare(fieldB) + : fieldB.localeCompare(fieldA); + }); + } else { + services.sort((a, b) => + order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort] + ); + } + + // If search exists... + if (search) { + // Filter the services + services = services.filter( + (contact: any) => + contact.name && + contact.name.toLowerCase().includes(search.toLowerCase()) + ); + } + + // Paginate - Start + const servicesLength = services.length; + + // Calculate pagination details + const begin = page * size; + const end = Math.min(size * (page + 1), servicesLength); + const lastPage = Math.max(Math.ceil(servicesLength / size), 1); + + // Prepare the pagination object + let pagination = {}; + + // If the requested page number is bigger than + // the last possible page number, return null for + // services but also send the last possible page so + // the app can navigate to there + if (page > lastPage) { + services = null; + pagination = { + lastPage, + }; + } else { + // Paginate the results by size + services = services.slice(begin, end); + + // Prepare the pagination mock-api + pagination = { + length: servicesLength, + size: size, + page: page, + lastPage: lastPage, + startIndex: begin, + endIndex: end - 1, + }; + } + + // Return the response + return [ + 200, + { + services, + pagination, + }, + ]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ Service - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/board/service/service') + .reply(({ request }) => { + // Get the id from the params + const id = request.params.get('id'); + + // Clone the services + const services = cloneDeep(this._services); + + // Find the service + const service = services.find((item: any) => item.id === id); + + // Return the response + return [200, service]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ Service - POST + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPost('api/apps/board/service/service') + .reply(() => { + // Generate a new service + const newService = { + id: FuseMockApiUtils.guid(), + category: '', + name: 'A New User', + description: '', + tags: [], + sku: '', + barcode: '', + brand: '', + vendor: '', + stock: '', + reserved: '', + cost: '', + basePrice: '', + taxPercent: '', + price: '', + weight: '', + thumbnail: '', + images: [], + active: false, + }; + + // Unshift the new service + this._services.unshift(newService); + + // Return the response + return [200, newService]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ Service - PATCH + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPatch('api/apps/board/service/service') + .reply(({ request }) => { + // Get the id and service + const id = request.body.id; + const service = cloneDeep(request.body.service); + + // Prepare the updated service + let updatedService = null; + + // Find the service and update it + this._services.forEach((item, index, services) => { + if (item.id === id) { + // Update the service + services[index] = assign({}, services[index], service); + + // Store the updated service + updatedService = services[index]; + } + }); + + // Return the response + return [200, updatedService]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ Service - DELETE + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onDelete('api/apps/board/service/service') + .reply(({ request }) => { + // Get the id + const id = request.params.get('id'); + + // Find the service and delete it + this._services.forEach((item, index) => { + if (item.id === id) { + this._services.splice(index, 1); + } + }); + + // Return the response + return [200, true]; + }); + } +} diff --git a/src/app/mock-api/apps/board/service/data.ts b/src/app/mock-api/apps/board/service/data.ts new file mode 100644 index 0000000..8f22976 --- /dev/null +++ b/src/app/mock-api/apps/board/service/data.ts @@ -0,0 +1,33 @@ +/* eslint-disable */ + +export const services = [ + { + id: 'on00', + totalPartnerCount: '5', + totalHoldingMoney: 303675, + totalComp: 108933, + total: 412608, + branchCount: 1, + divisionCount: 1, + officeCount: 1, + storeCount: 1, + memberCount: 1, + nickname: 'on00', + accountHolder: '11', + phoneNumber: '010-1111-1111', + calculateType: '롤링', + ownCash: 50000, + ownComp: 1711, + ownCoupon: 50000, + gameMoney: 0, + todayComp: 0, + totalDeposit: 0, + totalWithdraw: 0, + balance: 0, + registDate: '2022-06-12 15:38', + finalSigninDate: '', + ip: '', + state: '정상', + note: '', + }, +]; diff --git a/src/app/mock-api/common/navigation/data.ts b/src/app/mock-api/common/navigation/data.ts index 3f0f8fd..5f28468 100644 --- a/src/app/mock-api/common/navigation/data.ts +++ b/src/app/mock-api/common/navigation/data.ts @@ -160,6 +160,20 @@ export const defaultNavigation: FuseNavigationItem[] = [ icon: 'heroicons_outline:academic-cap', link: '/bank/withdraw', }, + { + id: 'bank.web-calculate', + title: 'Web Calculate', + type: 'basic', + icon: 'heroicons_outline:academic-cap', + link: '/bank/web-calculate', + }, + { + id: 'bank.partner-calculate', + title: 'Partner Calculate', + type: 'basic', + icon: 'heroicons_outline:academic-cap', + link: '/bank/partner-calculate', + }, ], }, { @@ -385,6 +399,20 @@ export const defaultNavigation: FuseNavigationItem[] = [ icon: 'heroicons_outline:academic-cap', link: '/board/popup', }, + { + id: 'board.message', + title: 'Message', + type: 'basic', + icon: 'heroicons_outline:academic-cap', + link: '/board/message', + }, + { + id: 'board.service', + title: 'Service', + type: 'basic', + icon: 'heroicons_outline:academic-cap', + link: '/board/service', + }, ], }, ]; diff --git a/src/app/mock-api/index.ts b/src/app/mock-api/index.ts index f3aa174..aad8377 100644 --- a/src/app/mock-api/index.ts +++ b/src/app/mock-api/index.ts @@ -36,6 +36,8 @@ import { TasksMockApi } from 'app/mock-api/apps/tasks/api'; import { UserMockApi } from 'app/mock-api/common/user/api'; import { BankDepositMockApi } from './apps/bank/deposit/api'; import { BankWithdrawMockApi } from './apps/bank/withdraw/api'; +import { BankWebCalculateMockApi } from './apps/bank/web-calculate/api'; +import { BankPartnerCalculateMockApi } from './apps/bank/partner-calculate/api'; import { GamePowerballMockApi } from './apps/game/powerball/api'; import { GameCasinoMockApi } from './apps/game/casino/api'; import { GameEvolutionMockApi } from './apps/game/evolution/api'; @@ -63,6 +65,8 @@ import { ReportLoosingMockApi } from './apps/report/loosing/api'; import { BoardNoticeMockApi } from './apps/board/notice/api'; import { BoardNoticeOnelineMockApi } from './apps/board/notice-oneline/api'; import { BoardPopupMockApi } from './apps/board/popup/api'; +import { BoardMessageMockApi } from './apps/board/message/api'; +import { BoardServiceMockApi } from './apps/board/service/api'; export const mockApiServices = [ AcademyMockApi, @@ -103,6 +107,8 @@ export const mockApiServices = [ UserMockApi, BankDepositMockApi, BankWithdrawMockApi, + BankWebCalculateMockApi, + BankPartnerCalculateMockApi, GamePowerballMockApi, GameCasinoMockApi, GameEvolutionMockApi, @@ -130,4 +136,6 @@ export const mockApiServices = [ BoardNoticeMockApi, BoardNoticeOnelineMockApi, BoardPopupMockApi, + BoardMessageMockApi, + BoardServiceMockApi, ]; diff --git a/src/app/modules/admin/bank/partner-calculate/components/index.ts b/src/app/modules/admin/bank/partner-calculate/components/index.ts new file mode 100644 index 0000000..04759eb --- /dev/null +++ b/src/app/modules/admin/bank/partner-calculate/components/index.ts @@ -0,0 +1,3 @@ +import { ListComponent } from './list.component'; + +export const COMPONENTS = [ListComponent]; diff --git a/src/app/modules/admin/bank/partner-calculate/components/list.component.html b/src/app/modules/admin/bank/partner-calculate/components/list.component.html new file mode 100644 index 0000000..eca0281 --- /dev/null +++ b/src/app/modules/admin/bank/partner-calculate/components/list.component.html @@ -0,0 +1,356 @@ +
+ +
+ +
+ +
+ +
파트너 입/출금정산
+ +
+ + + + + + + + + 카지노콤프 + 슬롯콤프 + 배팅콤프 + 첫충콤프 + + + + + 아이디 + 닉네임 + 이름 + 사이트 + 파트너수동지급 + + + + + + + + + +
+
+ + +
+ + +
+ + +
+ +
+
+ + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + +
+
+ + +
+ There are no Partner Calculate! +
+
+
+ +
+
diff --git a/src/app/modules/admin/bank/partner-calculate/components/list.component.ts b/src/app/modules/admin/bank/partner-calculate/components/list.component.ts new file mode 100644 index 0000000..3fd24b6 --- /dev/null +++ b/src/app/modules/admin/bank/partner-calculate/components/list.component.ts @@ -0,0 +1,192 @@ +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit, + ViewChild, + ViewEncapsulation, +} from '@angular/core'; +import { + FormBuilder, + FormControl, + FormGroup, + Validators, +} from '@angular/forms'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { + debounceTime, + map, + merge, + Observable, + Subject, + switchMap, + takeUntil, +} from 'rxjs'; +import { fuseAnimations } from '@fuse/animations'; +import { FuseConfirmationService } from '@fuse/services/confirmation'; + +import { User } from 'app/modules/admin/member/user/models/user'; +import { PartnerCalculate } from '../models/partner-calculate'; +import { PartnerCalculatePagination } from '../models/partner-calculate-pagination'; +import { PartnerCalculateService } from '../services/partner-calculate.service'; + +@Component({ + selector: 'bank-list', + templateUrl: './list.component.html', + styles: [ + /* language=SCSS */ + ` + .inventory-grid { + grid-template-columns: 60px auto 40px; + + @screen sm { + grid-template-columns: 60px auto 60px 72px; + } + + @screen md { + grid-template-columns: 60px 60px auto 112px 72px; + } + + @screen lg { + grid-template-columns: 60px 60px auto 112px 96px 96px 72px; + } + } + `, + ], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + animations: fuseAnimations, +}) +export class ListComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild(MatPaginator) private _paginator!: MatPaginator; + @ViewChild(MatSort) private _sort!: MatSort; + + partnerCalculates$!: Observable; + users$!: Observable; + + isLoading = false; + searchInputControl = new FormControl(); + selectedPartnerCalculate?: PartnerCalculate; + pagination?: PartnerCalculatePagination; + + private _unsubscribeAll: Subject = new Subject(); + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _fuseConfirmationService: FuseConfirmationService, + private _formBuilder: FormBuilder, + private _partnerCalculateService: PartnerCalculateService + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { + // Get the pagination + this._partnerCalculateService.pagination$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((pagination: PartnerCalculatePagination | undefined) => { + // Update the pagination + this.pagination = pagination; + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Get the products + this.partnerCalculates$ = this._partnerCalculateService.partnerCalculates$; + } + + /** + * After view init + */ + ngAfterViewInit(): void { + if (this._sort && this._paginator) { + // Set the initial sort + this._sort.sort({ + id: 'nickname', + start: 'asc', + disableClear: true, + }); + + // Mark for check + this._changeDetectorRef.markForCheck(); + + // If the partnerCalculate changes the sort order... + this._sort.sortChange + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + // Reset back to the first page + this._paginator.pageIndex = 0; + }); + + // Get products if sort or page changes + merge(this._sort.sortChange, this._paginator.page) + .pipe( + switchMap(() => { + this.isLoading = true; + return this._partnerCalculateService.getPartnerCalculates( + this._paginator.pageIndex, + this._paginator.pageSize, + this._sort.active, + this._sort.direction + ); + }), + map(() => { + this.isLoading = false; + }) + ) + .subscribe(); + } + } + + /** + * On destroy + */ + ngOnDestroy(): void { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(null); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create product + */ + __createProduct(): void {} + + /** + * Toggle product details + * + * @param productId + */ + __toggleDetails(productId: string): void {} + + /** + * Track by function for ngFor loops + * + * @param index + * @param item + */ + __trackByFn(index: number, item: any): any { + return item.id || index; + } +} diff --git a/src/app/modules/admin/bank/partner-calculate/models/partner-calculate-pagination.ts b/src/app/modules/admin/bank/partner-calculate/models/partner-calculate-pagination.ts new file mode 100644 index 0000000..f1ab11f --- /dev/null +++ b/src/app/modules/admin/bank/partner-calculate/models/partner-calculate-pagination.ts @@ -0,0 +1,8 @@ +export interface PartnerCalculatePagination { + length: number; + size: number; + page: number; + lastPage: number; + startIndex: number; + endIndex: number; +} diff --git a/src/app/modules/admin/bank/partner-calculate/models/partner-calculate.ts b/src/app/modules/admin/bank/partner-calculate/models/partner-calculate.ts new file mode 100644 index 0000000..dcf948d --- /dev/null +++ b/src/app/modules/admin/bank/partner-calculate/models/partner-calculate.ts @@ -0,0 +1,18 @@ +export interface PartnerCalculate { + id?: string; + rank?: string; + level?: string; + nickname?: string; + paymentDue?: number; + calculateType?: string; + accountHolder?: string; + note?: string; + registrationDate?: string; + processDate?: string; + deposit?: number; + withdraw?: number; + total?: number; + gameMoney?: number; + highRank?: string; + state?: string; +} diff --git a/src/app/modules/admin/bank/partner-calculate/partner-calculate.module.ts b/src/app/modules/admin/bank/partner-calculate/partner-calculate.module.ts new file mode 100644 index 0000000..8b392e3 --- /dev/null +++ b/src/app/modules/admin/bank/partner-calculate/partner-calculate.module.ts @@ -0,0 +1,42 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { MatButtonModule } from '@angular/material/button'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +import { MatSortModule } from '@angular/material/sort'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTooltipModule } from '@angular/material/tooltip'; + +import { TranslocoModule } from '@ngneat/transloco'; + +import { SharedModule } from 'app/shared/shared.module'; + +import { COMPONENTS } from './components'; + +import { partnerCalculateRoutes } from './partner-calculate.routing'; + +@NgModule({ + declarations: [COMPONENTS], + imports: [ + TranslocoModule, + SharedModule, + RouterModule.forChild(partnerCalculateRoutes), + + MatButtonModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatPaginatorModule, + MatProgressBarModule, + MatRippleModule, + MatSortModule, + MatSelectModule, + MatTooltipModule, + ], +}) +export class PartnerCalculateModule {} diff --git a/src/app/modules/admin/bank/partner-calculate/partner-calculate.routing.ts b/src/app/modules/admin/bank/partner-calculate/partner-calculate.routing.ts new file mode 100644 index 0000000..933522c --- /dev/null +++ b/src/app/modules/admin/bank/partner-calculate/partner-calculate.routing.ts @@ -0,0 +1,24 @@ +import { Route } from '@angular/router'; + +import { ListComponent } from './components/list.component'; +import { ViewComponent } from '../../member/user/components/view.component'; + +import { PartnerCalculatesResolver } from './resolvers/partner-calculate.resolver'; +import { UserResolver } from '../../dashboards/user/user.resolvers'; + +export const partnerCalculateRoutes: Route[] = [ + { + path: '', + component: ListComponent, + resolve: { + partnerCalculates: PartnerCalculatesResolver, + }, + }, + { + path: ':id', + component: ViewComponent, + resolve: { + users: UserResolver, + }, + }, +]; diff --git a/src/app/modules/admin/bank/partner-calculate/resolvers/partner-calculate.resolver.ts b/src/app/modules/admin/bank/partner-calculate/resolvers/partner-calculate.resolver.ts new file mode 100644 index 0000000..fc30483 --- /dev/null +++ b/src/app/modules/admin/bank/partner-calculate/resolvers/partner-calculate.resolver.ts @@ -0,0 +1,89 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + Resolve, + Router, + RouterStateSnapshot, +} from '@angular/router'; +import { catchError, Observable, throwError } from 'rxjs'; + +import { PartnerCalculate } from '../models/partner-calculate'; +import { PartnerCalculatePagination } from '../models/partner-calculate-pagination'; +import { PartnerCalculateService } from '../services/partner-calculate.service'; + +@Injectable({ + providedIn: 'root', +}) +export class PartnerCalculateResolver implements Resolve { + /** + * Constructor + */ + constructor( + private _partnerCalculateService: PartnerCalculateService, + private _router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable { + return this._partnerCalculateService + .getPartnerCalculateById(route.paramMap.get('id')) + .pipe( + // Error here means the requested product is not available + catchError((error) => { + // Log the error + console.error(error); + + // Get the parent url + const parentUrl = state.url.split('/').slice(0, -1).join('/'); + + // Navigate to there + this._router.navigateByUrl(parentUrl); + + // Throw an error + return throwError(error); + }) + ); + } +} + +@Injectable({ + providedIn: 'root', +}) +export class PartnerCalculatesResolver implements Resolve { + /** + * Constructor + */ + constructor(private _partnerCalculateService: PartnerCalculateService) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable<{ + pagination: PartnerCalculatePagination; + partnerCalculates: PartnerCalculate[]; + }> { + return this._partnerCalculateService.getPartnerCalculates(); + } +} diff --git a/src/app/modules/admin/bank/partner-calculate/services/partner-calculate.service.ts b/src/app/modules/admin/bank/partner-calculate/services/partner-calculate.service.ts new file mode 100644 index 0000000..22f0e25 --- /dev/null +++ b/src/app/modules/admin/bank/partner-calculate/services/partner-calculate.service.ts @@ -0,0 +1,161 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { + BehaviorSubject, + filter, + map, + Observable, + of, + switchMap, + take, + tap, + throwError, +} from 'rxjs'; + +import { PartnerCalculate } from '../models/partner-calculate'; +import { PartnerCalculatePagination } from '../models/partner-calculate-pagination'; + +@Injectable({ + providedIn: 'root', +}) +export class PartnerCalculateService { + // Private + private __pagination = new BehaviorSubject< + PartnerCalculatePagination | undefined + >(undefined); + private __partnerCalculate = new BehaviorSubject< + PartnerCalculate | undefined + >(undefined); + private __partnerCalculates = new BehaviorSubject< + PartnerCalculate[] | undefined + >(undefined); + + /** + * Constructor + */ + constructor(private _httpClient: HttpClient) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + /** + * Getter for pagination + */ + get pagination$(): Observable { + return this.__pagination.asObservable(); + } + + /** + * Getter for partnerCalculate + */ + get partnerCalculate$(): Observable { + return this.__partnerCalculate.asObservable(); + } + + /** + * Getter for partnerCalculates + */ + get partnerCalculates$(): Observable { + return this.__partnerCalculates.asObservable(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Get partnerCalculates + * + * + * @param page + * @param size + * @param sort + * @param order + * @param search + */ + getPartnerCalculates( + page: number = 0, + size: number = 10, + sort: string = 'nickname', + order: 'asc' | 'desc' | '' = 'asc', + search: string = '' + ): Observable<{ + pagination: PartnerCalculatePagination; + partnerCalculates: PartnerCalculate[]; + }> { + return this._httpClient + .get<{ + pagination: PartnerCalculatePagination; + partnerCalculates: PartnerCalculate[]; + }>('api/apps/bank/partner-calculate/partner-calculates', { + params: { + page: '' + page, + size: '' + size, + sort, + order, + search, + }, + }) + .pipe( + tap((response) => { + this.__pagination.next(response.pagination); + this.__partnerCalculates.next(response.partnerCalculates); + }) + ); + } + + /** + * Get product by id + */ + getPartnerCalculateById(id: string | null): Observable { + return this.__partnerCalculates.pipe( + take(1), + map((partnerCalculates) => { + // Find the product + const partnerCalculate = + partnerCalculates?.find((item) => item.id === id) || undefined; + + // Update the product + this.__partnerCalculate.next(partnerCalculate); + + // Return the product + return partnerCalculate; + }), + switchMap((product) => { + if (!product) { + return throwError('Could not found product with id of ' + id + '!'); + } + + return of(product); + }) + ); + } + + /** + * Create product + */ + createPartnerCalculate(): Observable { + return this.partnerCalculates$.pipe( + take(1), + switchMap((partnerCalculates) => + this._httpClient + .post('api/apps/bank/partner-calculate/product', {}) + .pipe( + map((newPartnerCalculate) => { + // Update the partnerCalculates with the new product + if (!!partnerCalculates) { + this.__partnerCalculates.next([ + newPartnerCalculate, + ...partnerCalculates, + ]); + } + + // Return the new product + return newPartnerCalculate; + }) + ) + ) + ); + } +} diff --git a/src/app/modules/admin/bank/web-calculate/components/index.ts b/src/app/modules/admin/bank/web-calculate/components/index.ts new file mode 100644 index 0000000..04759eb --- /dev/null +++ b/src/app/modules/admin/bank/web-calculate/components/index.ts @@ -0,0 +1,3 @@ +import { ListComponent } from './list.component'; + +export const COMPONENTS = [ListComponent]; diff --git a/src/app/modules/admin/bank/web-calculate/components/list.component.html b/src/app/modules/admin/bank/web-calculate/components/list.component.html new file mode 100644 index 0000000..8d164cd --- /dev/null +++ b/src/app/modules/admin/bank/web-calculate/components/list.component.html @@ -0,0 +1,348 @@ +
+ +
+ +
+ +
+ +
웹 입/출금정산
+ +
+ + + + + + + + + 카지노콤프 + 슬롯콤프 + 배팅콤프 + 첫충콤프 + + + + + 아이디 + 닉네임 + 이름 + 사이트 + 파트너수동지급 + + + + + + + + + +
+
+ + +
+ + +
+ + +
+ +
+
+ + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + +
+
+ + +
+ There are no Web Calculate! +
+
+
+ +
+
diff --git a/src/app/modules/admin/bank/web-calculate/components/list.component.ts b/src/app/modules/admin/bank/web-calculate/components/list.component.ts new file mode 100644 index 0000000..b8e5fd7 --- /dev/null +++ b/src/app/modules/admin/bank/web-calculate/components/list.component.ts @@ -0,0 +1,192 @@ +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit, + ViewChild, + ViewEncapsulation, +} from '@angular/core'; +import { + FormBuilder, + FormControl, + FormGroup, + Validators, +} from '@angular/forms'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { + debounceTime, + map, + merge, + Observable, + Subject, + switchMap, + takeUntil, +} from 'rxjs'; +import { fuseAnimations } from '@fuse/animations'; +import { FuseConfirmationService } from '@fuse/services/confirmation'; + +import { User } from 'app/modules/admin/member/user/models/user'; +import { WebCalculate } from '../models/web-calculate'; +import { WebCalculatePagination } from '../models/web-calculate-pagination'; +import { WebCalculateService } from '../services/web-calculate.service'; + +@Component({ + selector: 'bank-list', + templateUrl: './list.component.html', + styles: [ + /* language=SCSS */ + ` + .inventory-grid { + grid-template-columns: 60px auto 40px; + + @screen sm { + grid-template-columns: 60px auto 60px 72px; + } + + @screen md { + grid-template-columns: 60px 60px auto 112px 72px; + } + + @screen lg { + grid-template-columns: 60px 60px auto 112px 96px 96px 72px; + } + } + `, + ], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + animations: fuseAnimations, +}) +export class ListComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild(MatPaginator) private _paginator!: MatPaginator; + @ViewChild(MatSort) private _sort!: MatSort; + + webCalculates$!: Observable; + users$!: Observable; + + isLoading = false; + searchInputControl = new FormControl(); + selectedWebCalculate?: WebCalculate; + pagination?: WebCalculatePagination; + + private _unsubscribeAll: Subject = new Subject(); + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _fuseConfirmationService: FuseConfirmationService, + private _formBuilder: FormBuilder, + private _webCalculateService: WebCalculateService + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { + // Get the pagination + this._webCalculateService.pagination$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((pagination: WebCalculatePagination | undefined) => { + // Update the pagination + this.pagination = pagination; + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Get the products + this.webCalculates$ = this._webCalculateService.webCalculates$; + } + + /** + * After view init + */ + ngAfterViewInit(): void { + if (this._sort && this._paginator) { + // Set the initial sort + this._sort.sort({ + id: 'nickname', + start: 'asc', + disableClear: true, + }); + + // Mark for check + this._changeDetectorRef.markForCheck(); + + // If the webCalculate changes the sort order... + this._sort.sortChange + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + // Reset back to the first page + this._paginator.pageIndex = 0; + }); + + // Get products if sort or page changes + merge(this._sort.sortChange, this._paginator.page) + .pipe( + switchMap(() => { + this.isLoading = true; + return this._webCalculateService.getWebCalculates( + this._paginator.pageIndex, + this._paginator.pageSize, + this._sort.active, + this._sort.direction + ); + }), + map(() => { + this.isLoading = false; + }) + ) + .subscribe(); + } + } + + /** + * On destroy + */ + ngOnDestroy(): void { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(null); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create product + */ + __createProduct(): void {} + + /** + * Toggle product details + * + * @param productId + */ + __toggleDetails(productId: string): void {} + + /** + * Track by function for ngFor loops + * + * @param index + * @param item + */ + __trackByFn(index: number, item: any): any { + return item.id || index; + } +} diff --git a/src/app/modules/admin/bank/web-calculate/models/web-calculate-pagination.ts b/src/app/modules/admin/bank/web-calculate/models/web-calculate-pagination.ts new file mode 100644 index 0000000..7e77788 --- /dev/null +++ b/src/app/modules/admin/bank/web-calculate/models/web-calculate-pagination.ts @@ -0,0 +1,8 @@ +export interface WebCalculatePagination { + length: number; + size: number; + page: number; + lastPage: number; + startIndex: number; + endIndex: number; +} diff --git a/src/app/modules/admin/bank/web-calculate/models/web-calculate.ts b/src/app/modules/admin/bank/web-calculate/models/web-calculate.ts new file mode 100644 index 0000000..4ad295a --- /dev/null +++ b/src/app/modules/admin/bank/web-calculate/models/web-calculate.ts @@ -0,0 +1,18 @@ +export interface WebCalculate { + id?: string; + rank?: string; + level?: string; + nickname?: string; + paymentDue?: number; + calculateType?: string; + accountHolder?: string; + note?: string; + registrationDate?: string; + processDate?: string; + deposit?: number; + withdraw?: number; + total?: number; + gameMoney?: number; + highRank?: string; + state?: string; +} diff --git a/src/app/modules/admin/bank/web-calculate/resolvers/web-calculate.resolver.ts b/src/app/modules/admin/bank/web-calculate/resolvers/web-calculate.resolver.ts new file mode 100644 index 0000000..f59fcff --- /dev/null +++ b/src/app/modules/admin/bank/web-calculate/resolvers/web-calculate.resolver.ts @@ -0,0 +1,89 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + Resolve, + Router, + RouterStateSnapshot, +} from '@angular/router'; +import { catchError, Observable, throwError } from 'rxjs'; + +import { WebCalculate } from '../models/web-calculate'; +import { WebCalculatePagination } from '../models/web-calculate-pagination'; +import { WebCalculateService } from '../services/web-calculate.service'; + +@Injectable({ + providedIn: 'root', +}) +export class WebCalculateResolver implements Resolve { + /** + * Constructor + */ + constructor( + private _webCalculateService: WebCalculateService, + private _router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable { + return this._webCalculateService + .getWebCalculateById(route.paramMap.get('id')) + .pipe( + // Error here means the requested product is not available + catchError((error) => { + // Log the error + console.error(error); + + // Get the parent url + const parentUrl = state.url.split('/').slice(0, -1).join('/'); + + // Navigate to there + this._router.navigateByUrl(parentUrl); + + // Throw an error + return throwError(error); + }) + ); + } +} + +@Injectable({ + providedIn: 'root', +}) +export class WebCalculatesResolver implements Resolve { + /** + * Constructor + */ + constructor(private _webCalculateService: WebCalculateService) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable<{ + pagination: WebCalculatePagination; + webCalculates: WebCalculate[]; + }> { + return this._webCalculateService.getWebCalculates(); + } +} diff --git a/src/app/modules/admin/bank/web-calculate/services/web-calculate.service.ts b/src/app/modules/admin/bank/web-calculate/services/web-calculate.service.ts new file mode 100644 index 0000000..7809c13 --- /dev/null +++ b/src/app/modules/admin/bank/web-calculate/services/web-calculate.service.ts @@ -0,0 +1,158 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { + BehaviorSubject, + filter, + map, + Observable, + of, + switchMap, + take, + tap, + throwError, +} from 'rxjs'; + +import { WebCalculate } from '../models/web-calculate'; +import { WebCalculatePagination } from '../models/web-calculate-pagination'; + +@Injectable({ + providedIn: 'root', +}) +export class WebCalculateService { + // Private + private __pagination = new BehaviorSubject< + WebCalculatePagination | undefined + >(undefined); + private __webCalculate = new BehaviorSubject( + undefined + ); + private __webCalculates = new BehaviorSubject( + undefined + ); + + /** + * Constructor + */ + constructor(private _httpClient: HttpClient) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + /** + * Getter for pagination + */ + get pagination$(): Observable { + return this.__pagination.asObservable(); + } + + /** + * Getter for webCalculate + */ + get webCalculate$(): Observable { + return this.__webCalculate.asObservable(); + } + + /** + * Getter for webCalculates + */ + get webCalculates$(): Observable { + return this.__webCalculates.asObservable(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Get webCalculates + * + * + * @param page + * @param size + * @param sort + * @param order + * @param search + */ + getWebCalculates( + page: number = 0, + size: number = 10, + sort: string = 'nickname', + order: 'asc' | 'desc' | '' = 'asc', + search: string = '' + ): Observable<{ + pagination: WebCalculatePagination; + webCalculates: WebCalculate[]; + }> { + return this._httpClient + .get<{ + pagination: WebCalculatePagination; + webCalculates: WebCalculate[]; + }>('api/apps/bank/web-calculate/web-calculates', { + params: { + page: '' + page, + size: '' + size, + sort, + order, + search, + }, + }) + .pipe( + tap((response) => { + this.__pagination.next(response.pagination); + this.__webCalculates.next(response.webCalculates); + }) + ); + } + + /** + * Get product by id + */ + getWebCalculateById(id: string | null): Observable { + return this.__webCalculates.pipe( + take(1), + map((webCalculates) => { + // Find the product + const webCalculate = + webCalculates?.find((item) => item.id === id) || undefined; + + // Update the product + this.__webCalculate.next(webCalculate); + + // Return the product + return webCalculate; + }), + switchMap((product) => { + if (!product) { + return throwError('Could not found product with id of ' + id + '!'); + } + + return of(product); + }) + ); + } + + /** + * Create product + */ + createWebCalculate(): Observable { + return this.webCalculates$.pipe( + take(1), + switchMap((webCalculates) => + this._httpClient + .post('api/apps/bank/web-calculate/product', {}) + .pipe( + map((newWebCalculate) => { + // Update the webCalculates with the new product + if (!!webCalculates) { + this.__webCalculates.next([newWebCalculate, ...webCalculates]); + } + + // Return the new product + return newWebCalculate; + }) + ) + ) + ); + } +} diff --git a/src/app/modules/admin/bank/web-calculate/web-calculate.module.ts b/src/app/modules/admin/bank/web-calculate/web-calculate.module.ts new file mode 100644 index 0000000..26cd93a --- /dev/null +++ b/src/app/modules/admin/bank/web-calculate/web-calculate.module.ts @@ -0,0 +1,42 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { MatButtonModule } from '@angular/material/button'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +import { MatSortModule } from '@angular/material/sort'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTooltipModule } from '@angular/material/tooltip'; + +import { TranslocoModule } from '@ngneat/transloco'; + +import { SharedModule } from 'app/shared/shared.module'; + +import { COMPONENTS } from './components'; + +import { webCalculateRoutes } from './web-calculate.routing'; + +@NgModule({ + declarations: [COMPONENTS], + imports: [ + TranslocoModule, + SharedModule, + RouterModule.forChild(webCalculateRoutes), + + MatButtonModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatPaginatorModule, + MatProgressBarModule, + MatRippleModule, + MatSortModule, + MatSelectModule, + MatTooltipModule, + ], +}) +export class WebCalculateModule {} diff --git a/src/app/modules/admin/bank/web-calculate/web-calculate.routing.ts b/src/app/modules/admin/bank/web-calculate/web-calculate.routing.ts new file mode 100644 index 0000000..f0118a3 --- /dev/null +++ b/src/app/modules/admin/bank/web-calculate/web-calculate.routing.ts @@ -0,0 +1,24 @@ +import { Route } from '@angular/router'; + +import { ListComponent } from './components/list.component'; +import { ViewComponent } from '../../member/user/components/view.component'; + +import { WebCalculatesResolver } from './resolvers/web-calculate.resolver'; +import { UserResolver } from '../../dashboards/user/user.resolvers'; + +export const webCalculateRoutes: Route[] = [ + { + path: '', + component: ListComponent, + resolve: { + webCalculates: WebCalculatesResolver, + }, + }, + { + path: ':id', + component: ViewComponent, + resolve: { + users: UserResolver, + }, + }, +]; diff --git a/src/app/modules/admin/board/message/components/index.ts b/src/app/modules/admin/board/message/components/index.ts new file mode 100644 index 0000000..04759eb --- /dev/null +++ b/src/app/modules/admin/board/message/components/index.ts @@ -0,0 +1,3 @@ +import { ListComponent } from './list.component'; + +export const COMPONENTS = [ListComponent]; diff --git a/src/app/modules/admin/board/message/components/list.component.html b/src/app/modules/admin/board/message/components/list.component.html new file mode 100644 index 0000000..d9c77c4 --- /dev/null +++ b/src/app/modules/admin/board/message/components/list.component.html @@ -0,0 +1,355 @@ +
+ +
+ +
+ +
+ +
쪽지함
+ +
+ + + + + + + 40 + 60 + 80 + 100 + + + + + LV.1 + LV.2 + LV.3 + LV.4 + + + + + 정상 + 대기 + 탈퇴 + 휴면 + 블랙 + 정지 + + + + + 카지노제한 + 슬롯제한 + + + + + 계좌입금 + + + + + 카지노콤프 + 슬롯콤프 + 배팅콤프 + 첫충콤프 + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + +
+
+ + +
+ There are no messages! +
+
+
+
+
diff --git a/src/app/modules/admin/board/message/components/list.component.ts b/src/app/modules/admin/board/message/components/list.component.ts new file mode 100644 index 0000000..469b933 --- /dev/null +++ b/src/app/modules/admin/board/message/components/list.component.ts @@ -0,0 +1,198 @@ +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit, + ViewChild, + ViewEncapsulation, +} from '@angular/core'; +import { + FormBuilder, + FormControl, + FormGroup, + Validators, +} from '@angular/forms'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { + debounceTime, + map, + merge, + Observable, + Subject, + switchMap, + takeUntil, +} from 'rxjs'; +import { fuseAnimations } from '@fuse/animations'; +import { FuseConfirmationService } from '@fuse/services/confirmation'; + +import { User } from '../../../member/user/models/user'; +import { Message } from '../models/message'; +import { MessagePagination } from '../models/message-pagination'; +import { MessageService } from '../services/message.service'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'message-list', + templateUrl: './list.component.html', + styles: [ + /* language=SCSS */ + ` + .inventory-grid { + grid-template-columns: 60px auto 40px; + + @screen sm { + grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px; + } + + @screen md { + grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px 60px; + } + + @screen lg { + grid-template-columns: 60px 70px 70px 70px 70px 100px 60px 60px auto 60px 60px 60px 60px; + } + } + `, + ], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + animations: fuseAnimations, +}) +export class ListComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild(MatPaginator) private _paginator!: MatPaginator; + @ViewChild(MatSort) private _sort!: MatSort; + + messages$!: Observable; + users$!: Observable; + + isLoading = false; + searchInputControl = new FormControl(); + selectedMessage?: Message; + pagination?: MessagePagination; + + private _unsubscribeAll: Subject = new Subject(); + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _fuseConfirmationService: FuseConfirmationService, + private _formBuilder: FormBuilder, + private _messageService: MessageService, + private router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { + // Get the pagination + this._messageService.pagination$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((pagination: MessagePagination | undefined) => { + // Update the pagination + this.pagination = pagination; + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Get the products + this.messages$ = this._messageService.messages$; + } + + /** + * After view init + */ + ngAfterViewInit(): void { + if (this._sort && this._paginator) { + // Set the initial sort + this._sort.sort({ + id: 'name', + start: 'asc', + disableClear: true, + }); + + // Mark for check + this._changeDetectorRef.markForCheck(); + + // If the message changes the sort order... + this._sort.sortChange + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + // Reset back to the first page + this._paginator.pageIndex = 0; + }); + + // Get products if sort or page changes + merge(this._sort.sortChange, this._paginator.page) + .pipe( + switchMap(() => { + this.isLoading = true; + return this._messageService.getMessages( + this._paginator.pageIndex, + this._paginator.pageSize, + this._sort.active, + this._sort.direction + ); + }), + map(() => { + this.isLoading = false; + }) + ) + .subscribe(); + } + } + + /** + * On destroy + */ + ngOnDestroy(): void { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(null); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + viewUserDetail(id: string): void { + let url: string = 'member/user/' + id; + this.router.navigateByUrl(url); + } + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create product + */ + __createProduct(): void {} + + /** + * Toggle product details + * + * @param productId + */ + __toggleDetails(productId: string): void {} + + /** + * Track by function for ngFor loops + * + * @param index + * @param item + */ + __trackByFn(index: number, item: any): any { + return item.id || index; + } +} diff --git a/src/app/modules/admin/board/message/message.module.ts b/src/app/modules/admin/board/message/message.module.ts new file mode 100644 index 0000000..a8bc743 --- /dev/null +++ b/src/app/modules/admin/board/message/message.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { MatButtonModule } from '@angular/material/button'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +import { MatSortModule } from '@angular/material/sort'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatCheckboxModule } from '@angular/material/checkbox'; + +import { TranslocoModule } from '@ngneat/transloco'; + +import { SharedModule } from 'app/shared/shared.module'; + +import { COMPONENTS } from './components'; + +import { messageRoutes } from './message.routing'; + +@NgModule({ + declarations: [COMPONENTS], + imports: [ + TranslocoModule, + SharedModule, + RouterModule.forChild(messageRoutes), + + MatButtonModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatPaginatorModule, + MatProgressBarModule, + MatRippleModule, + MatSortModule, + MatSelectModule, + MatTooltipModule, + MatGridListModule, + MatSlideToggleModule, + MatRadioModule, + MatCheckboxModule, + ], +}) +export class MessageModule {} diff --git a/src/app/modules/admin/board/message/message.routing.ts b/src/app/modules/admin/board/message/message.routing.ts new file mode 100644 index 0000000..f558ba9 --- /dev/null +++ b/src/app/modules/admin/board/message/message.routing.ts @@ -0,0 +1,24 @@ +import { Route } from '@angular/router'; + +import { ListComponent } from './components/list.component'; +import { ViewComponent } from '../../member/user/components/view.component'; + +import { MessagesResolver } from './resolvers/message.resolver'; +import { UserResolver } from '../../member/user/resolvers/user.resolver'; + +export const messageRoutes: Route[] = [ + { + path: '', + component: ListComponent, + resolve: { + messages: MessagesResolver, + }, + }, + { + path: ':id', + component: ViewComponent, + resolve: { + users: UserResolver, + }, + }, +]; diff --git a/src/app/modules/admin/board/message/models/message-pagination.ts b/src/app/modules/admin/board/message/models/message-pagination.ts new file mode 100644 index 0000000..f21b49c --- /dev/null +++ b/src/app/modules/admin/board/message/models/message-pagination.ts @@ -0,0 +1,8 @@ +export interface MessagePagination { + length: number; + size: number; + page: number; + lastPage: number; + startIndex: number; + endIndex: number; +} diff --git a/src/app/modules/admin/board/message/models/message.ts b/src/app/modules/admin/board/message/models/message.ts new file mode 100644 index 0000000..9f760c9 --- /dev/null +++ b/src/app/modules/admin/board/message/models/message.ts @@ -0,0 +1,29 @@ +export interface Message { + id?: string; + totalPartnerCount?: number; + totalHoldingMoney?: number; + totalComp?: number; + total?: number; + branchCount?: number; + divisionCount?: number; + officeCount?: number; + storeCount?: number; + memberCount?: number; + nickname?: string; + accountHolder?: string; + phoneNumber?: string; + calculateType?: string; + ownCash?: number; + ownComp?: number; + ownCoupon?: number; + gameMoney?: number; + todayComp?: number; + totalDeposit?: number; + totalWithdraw?: number; + balance?: number; + registDate?: string; + finalSigninDate?: string; + ip?: string; + state?: string; + note?: string; +} diff --git a/src/app/modules/admin/board/message/resolvers/message.resolver.ts b/src/app/modules/admin/board/message/resolvers/message.resolver.ts new file mode 100644 index 0000000..c0a9054 --- /dev/null +++ b/src/app/modules/admin/board/message/resolvers/message.resolver.ts @@ -0,0 +1,87 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + Resolve, + Router, + RouterStateSnapshot, +} from '@angular/router'; +import { catchError, Observable, throwError } from 'rxjs'; + +import { Message } from '../models/message'; +import { MessagePagination } from '../models/message-pagination'; +import { MessageService } from '../services/message.service'; + +@Injectable({ + providedIn: 'root', +}) +export class MessageResolver implements Resolve { + /** + * Constructor + */ + constructor( + private _messageService: MessageService, + private _router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable { + return this._messageService.getMessageById(route.paramMap.get('id')).pipe( + // Error here means the requested product is not available + catchError((error) => { + // Log the error + console.error(error); + + // Get the parent url + const parentUrl = state.url.split('/').slice(0, -1).join('/'); + + // Navigate to there + this._router.navigateByUrl(parentUrl); + + // Throw an error + return throwError(error); + }) + ); + } +} + +@Injectable({ + providedIn: 'root', +}) +export class MessagesResolver implements Resolve { + /** + * Constructor + */ + constructor(private _messageService: MessageService) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable<{ + pagination: MessagePagination; + messages: Message[]; + }> { + return this._messageService.getMessages(); + } +} diff --git a/src/app/modules/admin/board/message/services/message.service.ts b/src/app/modules/admin/board/message/services/message.service.ts new file mode 100644 index 0000000..7fb7d3e --- /dev/null +++ b/src/app/modules/admin/board/message/services/message.service.ts @@ -0,0 +1,153 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { + BehaviorSubject, + filter, + map, + Observable, + of, + switchMap, + take, + tap, + throwError, +} from 'rxjs'; + +import { Message } from '../models/message'; +import { MessagePagination } from '../models/message-pagination'; + +@Injectable({ + providedIn: 'root', +}) +export class MessageService { + // Private + private __pagination = new BehaviorSubject( + undefined + ); + private __message = new BehaviorSubject(undefined); + private __messages = new BehaviorSubject(undefined); + + /** + * Constructor + */ + constructor(private _httpClient: HttpClient) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + /** + * Getter for pagination + */ + get pagination$(): Observable { + return this.__pagination.asObservable(); + } + + /** + * Getter for message + */ + get message$(): Observable { + return this.__message.asObservable(); + } + + /** + * Getter for messages + */ + get messages$(): Observable { + return this.__messages.asObservable(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Get Messages + * + * + * @param page + * @param size + * @param sort + * @param order + * @param search + */ + getMessages( + page: number = 0, + size: number = 10, + sort: string = 'name', + order: 'asc' | 'desc' | '' = 'asc', + search: string = '' + ): Observable<{ + pagination: MessagePagination; + messages: Message[]; + }> { + return this._httpClient + .get<{ + pagination: MessagePagination; + messages: Message[]; + }>('api/apps/board/message/messages', { + params: { + page: '' + page, + size: '' + size, + sort, + order, + search, + }, + }) + .pipe( + tap((response) => { + this.__pagination.next(response.pagination); + this.__messages.next(response.messages); + }) + ); + } + + /** + * Get product by id + */ + getMessageById(id: string | null): Observable { + return this.__messages.pipe( + take(1), + map((messages) => { + // Find the product + const message = messages?.find((item) => item.id === id) || undefined; + + // Update the product + this.__message.next(message); + + // Return the product + return message; + }), + switchMap((product) => { + if (!product) { + return throwError('Could not found product with id of ' + id + '!'); + } + + return of(product); + }) + ); + } + + /** + * Create product + */ + createMessage(): Observable { + return this.messages$.pipe( + take(1), + switchMap((messages) => + this._httpClient + .post('api/apps/board/message/product', {}) + .pipe( + map((newMessage) => { + // Update the messages with the new product + if (!!messages) { + this.__messages.next([newMessage, ...messages]); + } + + // Return the new product + return newMessage; + }) + ) + ) + ); + } +} diff --git a/src/app/modules/admin/board/notice/components/list.component.html b/src/app/modules/admin/board/notice/components/list.component.html index 3b0681f..4918cb5 100644 --- a/src/app/modules/admin/board/notice/components/list.component.html +++ b/src/app/modules/admin/board/notice/components/list.component.html @@ -15,19 +15,19 @@
+
+ +
+ +
+ +
고객센터
+ +
+ + + + + + + 40 + 60 + 80 + 100 + + + + + LV.1 + LV.2 + LV.3 + LV.4 + + + + + 정상 + 대기 + 탈퇴 + 휴면 + 블랙 + 정지 + + + + + 카지노제한 + 슬롯제한 + + + + + 계좌입금 + + + + + 카지노콤프 + 슬롯콤프 + 배팅콤프 + 첫충콤프 + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + +
+
+ + +
+ There are no services! +
+
+
+
+
diff --git a/src/app/modules/admin/board/service/components/list.component.ts b/src/app/modules/admin/board/service/components/list.component.ts new file mode 100644 index 0000000..486a0bb --- /dev/null +++ b/src/app/modules/admin/board/service/components/list.component.ts @@ -0,0 +1,198 @@ +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit, + ViewChild, + ViewEncapsulation, +} from '@angular/core'; +import { + FormBuilder, + FormControl, + FormGroup, + Validators, +} from '@angular/forms'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { + debounceTime, + map, + merge, + Observable, + Subject, + switchMap, + takeUntil, +} from 'rxjs'; +import { fuseAnimations } from '@fuse/animations'; +import { FuseConfirmationService } from '@fuse/services/confirmation'; + +import { User } from '../../../member/user/models/user'; +import { Service } from '../models/service'; +import { ServicePagination } from '../models/service-pagination'; +import { ServiceService } from '../services/service.service'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'service-list', + templateUrl: './list.component.html', + styles: [ + /* language=SCSS */ + ` + .inventory-grid { + grid-template-columns: 60px auto 40px; + + @screen sm { + grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px; + } + + @screen md { + grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px 60px; + } + + @screen lg { + grid-template-columns: 60px 70px 70px 70px 70px 100px 60px 60px auto 60px 60px 60px 60px; + } + } + `, + ], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + animations: fuseAnimations, +}) +export class ListComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild(MatPaginator) private _paginator!: MatPaginator; + @ViewChild(MatSort) private _sort!: MatSort; + + services$!: Observable; + users$!: Observable; + + isLoading = false; + searchInputControl = new FormControl(); + selectedService?: Service; + pagination?: ServicePagination; + + private _unsubscribeAll: Subject = new Subject(); + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _fuseConfirmationService: FuseConfirmationService, + private _formBuilder: FormBuilder, + private _serviceService: ServiceService, + private router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { + // Get the pagination + this._serviceService.pagination$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((pagination: ServicePagination | undefined) => { + // Update the pagination + this.pagination = pagination; + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Get the products + this.services$ = this._serviceService.services$; + } + + /** + * After view init + */ + ngAfterViewInit(): void { + if (this._sort && this._paginator) { + // Set the initial sort + this._sort.sort({ + id: 'name', + start: 'asc', + disableClear: true, + }); + + // Mark for check + this._changeDetectorRef.markForCheck(); + + // If the service changes the sort order... + this._sort.sortChange + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + // Reset back to the first page + this._paginator.pageIndex = 0; + }); + + // Get products if sort or page changes + merge(this._sort.sortChange, this._paginator.page) + .pipe( + switchMap(() => { + this.isLoading = true; + return this._serviceService.getServices( + this._paginator.pageIndex, + this._paginator.pageSize, + this._sort.active, + this._sort.direction + ); + }), + map(() => { + this.isLoading = false; + }) + ) + .subscribe(); + } + } + + /** + * On destroy + */ + ngOnDestroy(): void { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(null); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + viewUserDetail(id: string): void { + let url: string = 'member/user/' + id; + this.router.navigateByUrl(url); + } + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create product + */ + __createProduct(): void {} + + /** + * Toggle product details + * + * @param productId + */ + __toggleDetails(productId: string): void {} + + /** + * Track by function for ngFor loops + * + * @param index + * @param item + */ + __trackByFn(index: number, item: any): any { + return item.id || index; + } +} diff --git a/src/app/modules/admin/board/service/models/service-pagination.ts b/src/app/modules/admin/board/service/models/service-pagination.ts new file mode 100644 index 0000000..e50e908 --- /dev/null +++ b/src/app/modules/admin/board/service/models/service-pagination.ts @@ -0,0 +1,8 @@ +export interface ServicePagination { + length: number; + size: number; + page: number; + lastPage: number; + startIndex: number; + endIndex: number; +} diff --git a/src/app/modules/admin/board/service/models/service.ts b/src/app/modules/admin/board/service/models/service.ts new file mode 100644 index 0000000..b935e0b --- /dev/null +++ b/src/app/modules/admin/board/service/models/service.ts @@ -0,0 +1,29 @@ +export interface Service { + id?: string; + totalPartnerCount?: number; + totalHoldingMoney?: number; + totalComp?: number; + total?: number; + branchCount?: number; + divisionCount?: number; + officeCount?: number; + storeCount?: number; + memberCount?: number; + nickname?: string; + accountHolder?: string; + phoneNumber?: string; + calculateType?: string; + ownCash?: number; + ownComp?: number; + ownCoupon?: number; + gameMoney?: number; + todayComp?: number; + totalDeposit?: number; + totalWithdraw?: number; + balance?: number; + registDate?: string; + finalSigninDate?: string; + ip?: string; + state?: string; + note?: string; +} diff --git a/src/app/modules/admin/board/service/resolvers/service.resolver.ts b/src/app/modules/admin/board/service/resolvers/service.resolver.ts new file mode 100644 index 0000000..e2f3cd5 --- /dev/null +++ b/src/app/modules/admin/board/service/resolvers/service.resolver.ts @@ -0,0 +1,87 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + Resolve, + Router, + RouterStateSnapshot, +} from '@angular/router'; +import { catchError, Observable, throwError } from 'rxjs'; + +import { Service } from '../models/service'; +import { ServicePagination } from '../models/service-pagination'; +import { ServiceService } from '../services/service.service'; + +@Injectable({ + providedIn: 'root', +}) +export class ServiceResolver implements Resolve { + /** + * Constructor + */ + constructor( + private _serviceService: ServiceService, + private _router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable { + return this._serviceService.getServiceById(route.paramMap.get('id')).pipe( + // Error here means the requested product is not available + catchError((error) => { + // Log the error + console.error(error); + + // Get the parent url + const parentUrl = state.url.split('/').slice(0, -1).join('/'); + + // Navigate to there + this._router.navigateByUrl(parentUrl); + + // Throw an error + return throwError(error); + }) + ); + } +} + +@Injectable({ + providedIn: 'root', +}) +export class ServicesResolver implements Resolve { + /** + * Constructor + */ + constructor(private _serviceService: ServiceService) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable<{ + pagination: ServicePagination; + services: Service[]; + }> { + return this._serviceService.getServices(); + } +} diff --git a/src/app/modules/admin/board/service/service.module.ts b/src/app/modules/admin/board/service/service.module.ts new file mode 100644 index 0000000..56d9c0b --- /dev/null +++ b/src/app/modules/admin/board/service/service.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { MatButtonModule } from '@angular/material/button'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +import { MatSortModule } from '@angular/material/sort'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatCheckboxModule } from '@angular/material/checkbox'; + +import { TranslocoModule } from '@ngneat/transloco'; + +import { SharedModule } from 'app/shared/shared.module'; + +import { COMPONENTS } from './components'; + +import { serviceRoutes } from './service.routing'; + +@NgModule({ + declarations: [COMPONENTS], + imports: [ + TranslocoModule, + SharedModule, + RouterModule.forChild(serviceRoutes), + + MatButtonModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatPaginatorModule, + MatProgressBarModule, + MatRippleModule, + MatSortModule, + MatSelectModule, + MatTooltipModule, + MatGridListModule, + MatSlideToggleModule, + MatRadioModule, + MatCheckboxModule, + ], +}) +export class ServiceModule {} diff --git a/src/app/modules/admin/board/service/service.routing.ts b/src/app/modules/admin/board/service/service.routing.ts new file mode 100644 index 0000000..4be9d06 --- /dev/null +++ b/src/app/modules/admin/board/service/service.routing.ts @@ -0,0 +1,24 @@ +import { Route } from '@angular/router'; + +import { ListComponent } from './components/list.component'; +import { ViewComponent } from '../../member/user/components/view.component'; + +import { ServicesResolver } from './resolvers/service.resolver'; +import { UserResolver } from '../../member/user/resolvers/user.resolver'; + +export const serviceRoutes: Route[] = [ + { + path: '', + component: ListComponent, + resolve: { + services: ServicesResolver, + }, + }, + { + path: ':id', + component: ViewComponent, + resolve: { + users: UserResolver, + }, + }, +]; diff --git a/src/app/modules/admin/board/service/services/service.service.ts b/src/app/modules/admin/board/service/services/service.service.ts new file mode 100644 index 0000000..e8950af --- /dev/null +++ b/src/app/modules/admin/board/service/services/service.service.ts @@ -0,0 +1,153 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { + BehaviorSubject, + filter, + map, + Observable, + of, + switchMap, + take, + tap, + throwError, +} from 'rxjs'; + +import { Service } from '../models/service'; +import { ServicePagination } from '../models/service-pagination'; + +@Injectable({ + providedIn: 'root', +}) +export class ServiceService { + // Private + private __pagination = new BehaviorSubject( + undefined + ); + private __service = new BehaviorSubject(undefined); + private __services = new BehaviorSubject(undefined); + + /** + * Constructor + */ + constructor(private _httpClient: HttpClient) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + /** + * Getter for pagination + */ + get pagination$(): Observable { + return this.__pagination.asObservable(); + } + + /** + * Getter for service + */ + get service$(): Observable { + return this.__service.asObservable(); + } + + /** + * Getter for services + */ + get services$(): Observable { + return this.__services.asObservable(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Get Services + * + * + * @param page + * @param size + * @param sort + * @param order + * @param search + */ + getServices( + page: number = 0, + size: number = 10, + sort: string = 'name', + order: 'asc' | 'desc' | '' = 'asc', + search: string = '' + ): Observable<{ + pagination: ServicePagination; + services: Service[]; + }> { + return this._httpClient + .get<{ + pagination: ServicePagination; + services: Service[]; + }>('api/apps/board/service/services', { + params: { + page: '' + page, + size: '' + size, + sort, + order, + search, + }, + }) + .pipe( + tap((response) => { + this.__pagination.next(response.pagination); + this.__services.next(response.services); + }) + ); + } + + /** + * Get product by id + */ + getServiceById(id: string | null): Observable { + return this.__services.pipe( + take(1), + map((services) => { + // Find the product + const service = services?.find((item) => item.id === id) || undefined; + + // Update the product + this.__service.next(service); + + // Return the product + return service; + }), + switchMap((product) => { + if (!product) { + return throwError('Could not found product with id of ' + id + '!'); + } + + return of(product); + }) + ); + } + + /** + * Create product + */ + createService(): Observable { + return this.services$.pipe( + take(1), + switchMap((services) => + this._httpClient + .post('api/apps/board/service/product', {}) + .pipe( + map((newService) => { + // Update the services with the new product + if (!!services) { + this.__services.next([newService, ...services]); + } + + // Return the new product + return newService; + }) + ) + ) + ); + } +} diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index e88cd37..3ae9aff 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -19,6 +19,8 @@ "Analytics": "Analytics", "Deposit": "Deposit", "Withdraw": "Withdraw", + "Web Calculate": "Web Calculate", + "Partner Calculate": "Partner Calculate", "Powerball": "Powerball", "Casino": "Casino", "Evolution": "Evolution", @@ -40,5 +42,7 @@ "Loosing": "Loosing Management", "Notice": "Notice", "Notice Oneline": "Notice Oneline", - "Popup": "Pop Up" + "Popup": "Pop Up", + "Message": "Message", + "Service": "Service Center" } diff --git a/src/assets/i18n/ko.json b/src/assets/i18n/ko.json index ea95cc5..1c3901e 100644 --- a/src/assets/i18n/ko.json +++ b/src/assets/i18n/ko.json @@ -19,6 +19,8 @@ "Analytics": "Analytics", "Deposit": "입금관리", "Withdraw": "출금관리", + "Web Calculate": "웹 입/출금 정산", + "Partner Calculate": "파트너 입/출금 정산", "Powerball": "파워볼", "Casino": "카지노배팅리스트", "Evolution": "에볼루션배팅리스트", @@ -46,5 +48,7 @@ "Loosing": "루징관리", "Notice": "공지사항", "Notice Oneline": "한줄공지", - "Popup": "팝업" + "Popup": "팝업", + "Message": "쪽지함", + "Service": "고객센터" }