From 7f28adbe0be898d771af3276cda045f0838cbcd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=91=E8=87=A7=E6=8A=98=E6=9F=B3=E6=9B=B2?= <843391622@qq.com> Date: Wed, 25 Sep 2024 19:55:41 +0800 Subject: [PATCH 1/3] =?UTF-8?q?refactor(routes):=20=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.routes.ts | 2 +- .../bag-item-view/bag-item-view.component.ts | 2 +- .../reward-item-view.component.spec.ts | 45 +++++++++---------- .../reward-item-view.component.ts | 9 ++-- .../pages/challenge/challenge.component.ts | 9 ++-- .../pages/explore/explore.component.spec.ts | 45 +++++++++---------- .../quick-explore.component.less | 5 +++ .../quick-explore.component.spec.ts | 45 +++++++++---------- src/app/pages/challenge/routes.ts | 1 + 9 files changed, 84 insertions(+), 79 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 1ec741b..6e3c37d 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -2,9 +2,9 @@ import { Routes } from '@angular/router'; import { startPageGuard } from './guards/start-page.guard'; import { HomeComponent } from './pages/home/home.component'; -import { UniverseComponent } from './pages/universe/universe.component'; import { MethodComponent } from './pages/method/method.component'; import { ShopComponent } from './pages/shop/shop.component'; +import { UniverseComponent } from './pages/universe/universe.component'; export const routes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, diff --git a/src/app/components/bag-item-view/bag-item-view.component.ts b/src/app/components/bag-item-view/bag-item-view.component.ts index 7c26da9..0566fbc 100644 --- a/src/app/components/bag-item-view/bag-item-view.component.ts +++ b/src/app/components/bag-item-view/bag-item-view.component.ts @@ -2,11 +2,11 @@ import { CommonModule } from '@angular/common'; import { Component, inject, Input } from '@angular/core'; import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzCardModule } from 'ng-zorro-antd/card'; -import { BagItem, getItemLevelClass, ItemLevelMap, ItemMap } from '../../models/item.model'; import { NzMessageModule, NzMessageService } from 'ng-zorro-antd/message'; import { NzPopoverModule } from 'ng-zorro-antd/popover'; import { LogType, LogLevel } from '../../models'; +import { BagItem, getItemLevelClass, ItemLevelMap, ItemMap } from '../../models/item.model'; import { BackpackService } from '../../services/backpack.service'; import { LogService } from '../../services/log.service'; diff --git a/src/app/components/reward-item-view/reward-item-view.component.spec.ts b/src/app/components/reward-item-view/reward-item-view.component.spec.ts index ec3fa92..9d77279 100644 --- a/src/app/components/reward-item-view/reward-item-view.component.spec.ts +++ b/src/app/components/reward-item-view/reward-item-view.component.spec.ts @@ -1,23 +1,22 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { RewardItemViewComponent } from './reward-item-view.component'; - -describe('RewardItemViewComponent', () => { - let component: RewardItemViewComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [RewardItemViewComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(RewardItemViewComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RewardItemViewComponent } from './reward-item-view.component'; + +describe('RewardItemViewComponent', () => { + let component: RewardItemViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RewardItemViewComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(RewardItemViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/reward-item-view/reward-item-view.component.ts b/src/app/components/reward-item-view/reward-item-view.component.ts index bdc984a..2b51c59 100644 --- a/src/app/components/reward-item-view/reward-item-view.component.ts +++ b/src/app/components/reward-item-view/reward-item-view.component.ts @@ -1,7 +1,8 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { getItemLevelClass, Item, ItemLevelMap, ItemMap, RewardPool } from '../../models'; -import { NzCardModule } from 'ng-zorro-antd/card'; import { CommonModule } from '@angular/common'; +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { NzCardModule } from 'ng-zorro-antd/card'; + +import { getItemLevelClass, Item, ItemLevelMap, ItemMap, RewardPool } from '../../models'; @Component({ selector: 'app-reward-item-view', @@ -11,7 +12,7 @@ import { CommonModule } from '@angular/common'; styleUrl: './reward-item-view.component.less', changeDetection: ChangeDetectionStrategy.OnPush }) -export class RewardItemViewComponent { +export class RewardItemViewComponent implements OnInit { @Input() reward: RewardPool = []; rewardItems: Item[] = []; diff --git a/src/app/pages/challenge/challenge.component.ts b/src/app/pages/challenge/challenge.component.ts index 3339258..7eb528c 100644 --- a/src/app/pages/challenge/challenge.component.ts +++ b/src/app/pages/challenge/challenge.component.ts @@ -1,11 +1,12 @@ import { Component, inject } from '@angular/core'; -import { Challenge, RewardPoolMap } from '../../models'; +import { Router } from '@angular/router'; +import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzCardModule } from 'ng-zorro-antd/card'; +import { NzTagModule } from 'ng-zorro-antd/tag'; + import { RewardItemViewComponent } from '../../components/reward-item-view/reward-item-view.component'; +import { Challenge, RewardPoolMap } from '../../models'; import { EnvService } from '../../services/env.service'; -import { NzTagModule } from 'ng-zorro-antd/tag'; -import { NzButtonModule } from 'ng-zorro-antd/button'; -import { Router } from '@angular/router'; @Component({ selector: 'app-challenge', diff --git a/src/app/pages/challenge/pages/explore/explore.component.spec.ts b/src/app/pages/challenge/pages/explore/explore.component.spec.ts index 365a693..7f719c8 100644 --- a/src/app/pages/challenge/pages/explore/explore.component.spec.ts +++ b/src/app/pages/challenge/pages/explore/explore.component.spec.ts @@ -1,23 +1,22 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ExploreComponent } from './explore.component'; - -describe('ExploreComponent', () => { - let component: ExploreComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ExploreComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(ExploreComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ExploreComponent } from './explore.component'; + +describe('ExploreComponent', () => { + let component: ExploreComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ExploreComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(ExploreComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/challenge/pages/quick-explore/quick-explore.component.less b/src/app/pages/challenge/pages/quick-explore/quick-explore.component.less index e69de29..2b38e9c 100644 --- a/src/app/pages/challenge/pages/quick-explore/quick-explore.component.less +++ b/src/app/pages/challenge/pages/quick-explore/quick-explore.component.less @@ -0,0 +1,5 @@ +:host { + flex: 1; + height: 0; + overflow: auto; +} diff --git a/src/app/pages/challenge/pages/quick-explore/quick-explore.component.spec.ts b/src/app/pages/challenge/pages/quick-explore/quick-explore.component.spec.ts index 8963440..ed64db7 100644 --- a/src/app/pages/challenge/pages/quick-explore/quick-explore.component.spec.ts +++ b/src/app/pages/challenge/pages/quick-explore/quick-explore.component.spec.ts @@ -1,23 +1,22 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { QuickExploreComponent } from './quick-explore.component'; - -describe('QuickExploreComponent', () => { - let component: QuickExploreComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [QuickExploreComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(QuickExploreComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { QuickExploreComponent } from './quick-explore.component'; + +describe('QuickExploreComponent', () => { + let component: QuickExploreComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [QuickExploreComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(QuickExploreComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/challenge/routes.ts b/src/app/pages/challenge/routes.ts index 13f43d7..03ed087 100644 --- a/src/app/pages/challenge/routes.ts +++ b/src/app/pages/challenge/routes.ts @@ -1,4 +1,5 @@ import { Routes } from '@angular/router'; + import { ChallengeComponent } from './challenge.component'; import { ExploreComponent } from './pages/explore/explore.component'; import { QuickExploreComponent } from './pages/quick-explore/quick-explore.component'; From 6419ddf3bf6b328b4c7552ffe872f5ec7ba2567d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=91=E8=87=A7=E6=8A=98=E6=9F=B3=E6=9B=B2?= <843391622@qq.com> Date: Wed, 25 Sep 2024 20:35:12 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat(=E4=BB=BB=E5=8A=A1=E7=B3=BB=E7=BB=9F):?= =?UTF-8?q?=20=E6=95=B0=E6=8D=AE=E5=AD=98=E5=82=A8=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E5=92=8C=E4=BB=BB=E5=8A=A1=E7=B3=BB=E7=BB=9F=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.component.ts | 11 ++++- .../sider/components/task/task.component.html | 19 ++++++++- .../sider/components/task/task.component.ts | 19 +++++++-- src/app/layouts/sider/sider.component.html | 2 +- src/app/models/index.ts | 18 +++++---- src/app/models/runtime.model.ts | 12 ++++++ src/app/models/task.model.ts | 40 +++++++++++++++++++ src/app/pages/home/home.component.html | 2 +- src/app/services/runtime.service.ts | 22 +++++----- src/app/services/task.service.spec.ts | 16 ++++++++ src/app/services/task.service.ts | 32 +++++++++++++++ 11 files changed, 168 insertions(+), 25 deletions(-) create mode 100644 src/app/models/runtime.model.ts create mode 100644 src/app/models/task.model.ts create mode 100644 src/app/services/task.service.spec.ts create mode 100644 src/app/services/task.service.ts diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 7709c6f..96065d8 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -9,6 +9,7 @@ import { InitModalComponent } from './components/init-modal/init-modal.component import { CharacterComponent } from './layouts/character/character.component'; import { HeaderComponent } from './layouts/header/header.component'; import { SiderComponent } from './layouts/sider/sider.component'; +import { TASKS } from './models'; import { HomeComponent } from './pages/home/home.component'; import { UniverseComponent } from './pages/universe/universe.component'; import { RuntimeService } from './services/runtime.service'; @@ -34,7 +35,7 @@ export class AppComponent implements OnInit { ngOnInit() { this.rtSrv.load().then(data => { if (data) { - this.rtSrv.init(data.runtimeData, data.characterData, data.envData, data.backpackData); + this.rtSrv.init(data); } else { this.init(); } @@ -60,7 +61,13 @@ export class AppComponent implements OnInit { nzWidth: '1000px' }) .afterClose.subscribe(({ character, env }) => { - this.rtSrv.init({ tick: Math.round(Math.random() * 100) }, character, env); + this.rtSrv.init({ + runtimeData: { tick: Math.round(Math.random() * 100) }, + characterData: character, + envData: env, + backpackData: [], + taskData: '1' + }); }); } diff --git a/src/app/layouts/sider/components/task/task.component.html b/src/app/layouts/sider/components/task/task.component.html index 59f1a25..09d787a 100644 --- a/src/app/layouts/sider/components/task/task.component.html +++ b/src/app/layouts/sider/components/task/task.component.html @@ -1,2 +1,19 @@
任务面板
-
+
+ @if (currentTask) { +
+
{{ currentTask.title }}
+

任务描述:{{ currentTask.description }}

+

任务奖励: + @for (reward of currentTask.rewards; track $index) { + {{ ItemMap[reward.id].name }} * {{ reward.count }} + } +

+
+ } @else { +
+ +
+ } +
diff --git a/src/app/layouts/sider/components/task/task.component.ts b/src/app/layouts/sider/components/task/task.component.ts index 944be17..039177e 100644 --- a/src/app/layouts/sider/components/task/task.component.ts +++ b/src/app/layouts/sider/components/task/task.component.ts @@ -1,10 +1,23 @@ -import { Component } from '@angular/core'; +import { Component, inject, OnInit } from '@angular/core'; +import { NzEmptyModule } from 'ng-zorro-antd/empty'; import { NzTypographyModule } from 'ng-zorro-antd/typography'; +import { ItemMap, Task } from '../../../../models'; +import { TaskService } from '../../../../services/task.service'; + @Component({ selector: 'app-task', standalone: true, - imports: [NzTypographyModule], + imports: [NzTypographyModule, NzEmptyModule], templateUrl: './task.component.html' }) -export class TaskComponent {} +export class TaskComponent implements OnInit { + private taskSrv = inject(TaskService); + currentTask: Task | undefined; + + ItemMap = ItemMap; + + ngOnInit(): void { + this.taskSrv.task$.subscribe(task => (this.currentTask = task)); + } +} diff --git a/src/app/layouts/sider/sider.component.html b/src/app/layouts/sider/sider.component.html index 11d9916..15e10f5 100644 --- a/src/app/layouts/sider/sider.component.html +++ b/src/app/layouts/sider/sider.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/app/models/index.ts b/src/app/models/index.ts index 01c4672..991305d 100644 --- a/src/app/models/index.ts +++ b/src/app/models/index.ts @@ -1,8 +1,10 @@ -export * from './character.model'; -export * from './env.model'; -export * from './log.model'; -export * from './buff.model'; -export * from './battle.model'; -export * from './challenge.model'; -export * from './reward.model'; -export * from './item.model'; +export * from './battle.model'; // 战斗 +export * from './buff.model'; // buff +export * from './challenge.model'; // 副本 +export * from './character.model'; // 角色 +export * from './env.model'; // 环境 +export * from './item.model'; // 物品 +export * from './log.model'; // 日志 +export * from './reward.model'; // 奖励池 +export * from './runtime.model'; // 运行时 +export * from './task.model'; // 任务 diff --git a/src/app/models/runtime.model.ts b/src/app/models/runtime.model.ts new file mode 100644 index 0000000..3d1fd80 --- /dev/null +++ b/src/app/models/runtime.model.ts @@ -0,0 +1,12 @@ +import { Character } from './character.model'; +import { Env } from './env.model'; +import { BagItem } from './item.model'; +import { Task } from './task.model'; + +export interface StorageData { + runtimeData: { tick: number }; // 时间刻 + characterData: Character; // 角色信息 + envData: Env; // 环境信息 + backpackData: BagItem[]; // 背包信息 + taskData: string; // 任务信息 +} diff --git a/src/app/models/task.model.ts b/src/app/models/task.model.ts new file mode 100644 index 0000000..aedf125 --- /dev/null +++ b/src/app/models/task.model.ts @@ -0,0 +1,40 @@ +export interface Task { + id: number; + nextId: number; + title: string; + description: string; + rewards: TaskReward[]; + isCompleted: boolean; + watcher: Function; +} + +export interface TaskReward { + id: string; + count: number; +} + +export const TASKS: Record = { + 1: { + id: 1, + nextId: 2, + title: '开始修炼', + description: '点击开始修炼按钮,完成第一次修炼', + rewards: [ + { + id: '1', + count: 100 + } + ], + isCompleted: false, + watcher: () => {} + }, + 2: { + id: 2, + nextId: 3, + title: 'Task 2', + description: 'This is the second task', + rewards: [], + isCompleted: false, + watcher: () => {} + } +}; diff --git a/src/app/pages/home/home.component.html b/src/app/pages/home/home.component.html index 53db5ac..99c2215 100644 --- a/src/app/pages/home/home.component.html +++ b/src/app/pages/home/home.component.html @@ -1,4 +1,4 @@ -
+
洞府
diff --git a/src/app/services/runtime.service.ts b/src/app/services/runtime.service.ts index e7521c1..62e7f73 100644 --- a/src/app/services/runtime.service.ts +++ b/src/app/services/runtime.service.ts @@ -3,11 +3,11 @@ import * as CryptoJS from 'crypto-js'; import { NzNotificationService } from 'ng-zorro-antd/notification'; import { BehaviorSubject, Observable, timer } from 'rxjs'; -import { Character, Env } from '../models'; -import { BagItem } from '../models/item.model'; +import { StorageData, TASKS } from '../models'; import { BackpackService } from './backpack.service'; import { CharacterService } from './character.service'; import { EnvService } from './env.service'; +import { TaskService } from './task.service'; const WANJIE_TOKEN = 'wanjie_data'; @@ -19,6 +19,7 @@ export class RuntimeService { private envSrv = inject(EnvService); private notice = inject(NzNotificationService); private backpackSrv = inject(BackpackService); + private taskSrv = inject(TaskService); isInit: boolean = false; timeTick: BehaviorSubject = new BehaviorSubject(0); @@ -32,11 +33,12 @@ export class RuntimeService { } } - init(runtimeData: { tick: number }, characterData: Partial, envData: Env, backpackData?: BagItem[]) { - this.characterSrv.setCharacter(characterData); - this.envSrv.setEnv(envData); - this.timeTick.next(runtimeData.tick); - if (backpackData) this.backpackSrv.loadItems(backpackData); + init(storageData: StorageData) { + this.characterSrv.setCharacter(storageData.characterData); + this.envSrv.setEnv(storageData.envData); + this.timeTick.next(storageData.runtimeData.tick); + this.backpackSrv.loadItems(storageData.backpackData); + this.taskSrv.setCurrentTask(TASKS[storageData.taskData]); this.isInit = true; } @@ -44,6 +46,7 @@ export class RuntimeService { const characterData = this.characterSrv.getCharacter(); const envData = this.envSrv.getEnv(); const backpackData = this.backpackSrv.saveItems(); + const taskData = this.taskSrv.getCurrentTask()?.id; const time = new Date(); localStorage.setItem( WANJIE_TOKEN, @@ -55,7 +58,8 @@ export class RuntimeService { }, characterData, envData, - backpackData + backpackData, + taskData }), WANJIE_TOKEN ).toString() @@ -63,7 +67,7 @@ export class RuntimeService { this.notice.success('保存成功', `您的数据已保存,本次保存时间为${time.toLocaleString()}`); } - load(): Promise<{ runtimeData: { tick: number }; characterData: Character; envData: Env; backpackData: BagItem[] } | null> { + load(): Promise { const data = localStorage.getItem(WANJIE_TOKEN); if (data) { const parseData = JSON.parse(CryptoJS.AES.decrypt(data, WANJIE_TOKEN).toString(CryptoJS.enc.Utf8)); diff --git a/src/app/services/task.service.spec.ts b/src/app/services/task.service.spec.ts new file mode 100644 index 0000000..0bbd214 --- /dev/null +++ b/src/app/services/task.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { TaskService } from './task.service'; + +describe('TaskService', () => { + let service: TaskService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(TaskService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/task.service.ts b/src/app/services/task.service.ts new file mode 100644 index 0000000..1cc0e0e --- /dev/null +++ b/src/app/services/task.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs'; + +import { Task, TASKS } from '../models'; + +@Injectable({ + providedIn: 'root' +}) +export class TaskService { + currentTask: Task | undefined; + taskSub: Subject = new Subject(); + task$ = this.taskSub.asObservable(); + + initTask(): void { + this.setCurrentTask(TASKS[0]); + } + + complatedTask(task: Task): void { + const nextTask = TASKS[task.nextId] || undefined; + if (!nextTask) return; + this.setCurrentTask(nextTask); + } + + setCurrentTask(task: Task) { + this.currentTask = task; + this.taskSub.next(task); + } + + getCurrentTask(): Task | undefined { + return this.currentTask; + } +} From 0f5a7c299b52e3bfb909ffed1261e820aa9c6279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=91=E8=87=A7=E6=8A=98=E6=9F=B3=E6=9B=B2?= <843391622@qq.com> Date: Wed, 25 Sep 2024 21:23:09 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat(=E4=BB=BB=E5=8A=A1=E7=B3=BB=E7=BB=9F):?= =?UTF-8?q?=20=E4=BB=BB=E5=8A=A1=E7=BB=84=E4=BB=B6=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=92=8C=E7=BB=9F=E8=AE=A1=E6=9C=8D=E5=8A=A1=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sider/components/task/task.component.html | 24 ++++++++---- .../sider/components/task/task.component.ts | 37 +++++++++++++++++-- src/app/models/index.ts | 1 + src/app/models/statistics.model.ts | 13 +++++++ src/app/models/task.model.ts | 17 +++++++-- src/app/services/character.service.ts | 9 ++++- src/app/services/statistics.service.spec.ts | 16 ++++++++ src/app/services/statistics.service.ts | 31 ++++++++++++++++ src/app/services/task.service.ts | 7 ++-- 9 files changed, 137 insertions(+), 18 deletions(-) create mode 100644 src/app/models/statistics.model.ts create mode 100644 src/app/services/statistics.service.spec.ts create mode 100644 src/app/services/statistics.service.ts diff --git a/src/app/layouts/sider/components/task/task.component.html b/src/app/layouts/sider/components/task/task.component.html index 09d787a..b9d8d53 100644 --- a/src/app/layouts/sider/components/task/task.component.html +++ b/src/app/layouts/sider/components/task/task.component.html @@ -1,15 +1,23 @@
任务面板
@if (currentTask) { -
-
{{ currentTask.title }}
-

任务描述:{{ currentTask.description }}

-

任务奖励: - @for (reward of currentTask.rewards; track $index) { - {{ ItemMap[reward.id].name }} * {{ reward.count }} +

+
+
{{ currentTask.title }}
+

任务描述:{{ currentTask.description }}

+

+ 任务奖励: + @for (reward of currentTask.rewards; track $index) { + {{ ItemMap[reward.id].name }} * {{ reward.count }} + } +

+

完成情况:{{ currentTask.isCompleted ? '已完成' : '未完成' }}

+
+
+ @if (currentTask.isCompleted) { + } -

+
} @else {
diff --git a/src/app/layouts/sider/components/task/task.component.ts b/src/app/layouts/sider/components/task/task.component.ts index 039177e..52759a2 100644 --- a/src/app/layouts/sider/components/task/task.component.ts +++ b/src/app/layouts/sider/components/task/task.component.ts @@ -1,23 +1,54 @@ import { Component, inject, OnInit } from '@angular/core'; +import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzEmptyModule } from 'ng-zorro-antd/empty'; import { NzTypographyModule } from 'ng-zorro-antd/typography'; -import { ItemMap, Task } from '../../../../models'; +import { getItemLevelClass, ItemMap, LogLevel, LogType, Task } from '../../../../models'; +import { BackpackService } from '../../../../services/backpack.service'; +import { LogService } from '../../../../services/log.service'; +import { StatisticsService } from '../../../../services/statistics.service'; import { TaskService } from '../../../../services/task.service'; @Component({ selector: 'app-task', standalone: true, - imports: [NzTypographyModule, NzEmptyModule], + imports: [NzTypographyModule, NzEmptyModule, NzButtonModule], templateUrl: './task.component.html' }) export class TaskComponent implements OnInit { private taskSrv = inject(TaskService); + private statisticsService = inject(StatisticsService); + private backpackSrv = inject(BackpackService); + private logSrv = inject(LogService); currentTask: Task | undefined; - ItemMap = ItemMap; ngOnInit(): void { this.taskSrv.task$.subscribe(task => (this.currentTask = task)); + this.statisticsService.statistics$.subscribe(event => { + if (!this.currentTask) return; + this.currentTask.isCompleted = this.currentTask.conditions.every( + condition => + condition.type === event.type && + condition.field === event.field && + condition.count <= this.statisticsService.getValue(condition.type, condition.field) + ); + }); + } + + onGetRewardClick() { + if (!this.currentTask) return; + let msg: string = ''; + this.currentTask.rewards.forEach(reward => { + const item = ItemMap[reward.id]; + this.backpackSrv.addItem(item, reward.count); + msg += `${item.name} * ${reward.count} `; + }); + this.logSrv.log({ + msg: `完成任务,获得奖励:${msg}`, + type: LogType.Item, + level: LogLevel.Info + }); + this.currentTask && this.taskSrv.complatedTask(this.currentTask); } } diff --git a/src/app/models/index.ts b/src/app/models/index.ts index 991305d..07b6ff9 100644 --- a/src/app/models/index.ts +++ b/src/app/models/index.ts @@ -7,4 +7,5 @@ export * from './item.model'; // 物品 export * from './log.model'; // 日志 export * from './reward.model'; // 奖励池 export * from './runtime.model'; // 运行时 +export * from './statistics.model'; // 统计 export * from './task.model'; // 任务 diff --git a/src/app/models/statistics.model.ts b/src/app/models/statistics.model.ts new file mode 100644 index 0000000..805f600 --- /dev/null +++ b/src/app/models/statistics.model.ts @@ -0,0 +1,13 @@ +export interface CharacterStatistics { + cultivationCount: number; +} + +export interface StatisticsEvent { + type: StatisticsEventType; + field: string; + count: number; +} + +export enum StatisticsEventType { + Character +} diff --git a/src/app/models/task.model.ts b/src/app/models/task.model.ts index aedf125..202d113 100644 --- a/src/app/models/task.model.ts +++ b/src/app/models/task.model.ts @@ -1,3 +1,8 @@ +import { inject } from '@angular/core'; + +import { StatisticsService } from '../services/statistics.service'; +import { StatisticsEvent, StatisticsEventType } from './statistics.model'; + export interface Task { id: number; nextId: number; @@ -5,7 +10,7 @@ export interface Task { description: string; rewards: TaskReward[]; isCompleted: boolean; - watcher: Function; + conditions: StatisticsEvent[]; } export interface TaskReward { @@ -26,7 +31,13 @@ export const TASKS: Record = { } ], isCompleted: false, - watcher: () => {} + conditions: [ + { + type: StatisticsEventType.Character, + field: 'cultivationCount', + count: 1 + } + ] }, 2: { id: 2, @@ -35,6 +46,6 @@ export const TASKS: Record = { description: 'This is the second task', rewards: [], isCompleted: false, - watcher: () => {} + conditions: [] } }; diff --git a/src/app/services/character.service.ts b/src/app/services/character.service.ts index 02adc97..1ad7083 100644 --- a/src/app/services/character.service.ts +++ b/src/app/services/character.service.ts @@ -1,8 +1,9 @@ import { inject, Injectable } from '@angular/core'; -import { BaseInfo, Character, LogLevel, LogType, SkillInfo, StatusInfo, LevelInfo, AttrInfo } from '../models'; +import { BaseInfo, Character, LogLevel, LogType, SkillInfo, StatusInfo, LevelInfo, AttrInfo, StatisticsEventType } from '../models'; import { EnvService } from './env.service'; import { LogService } from './log.service'; +import { StatisticsService } from './statistics.service'; @Injectable({ providedIn: 'root' @@ -10,6 +11,7 @@ import { LogService } from './log.service'; export class CharacterService { private envSrv = inject(EnvService); private logSrv = inject(LogService); + private statisticsSrv = inject(StatisticsService); id: string = ''; baseInfo: BaseInfo = { @@ -46,6 +48,11 @@ export class CharacterService { }; cultivation(): Promise { + this.statisticsSrv.update({ + type: StatisticsEventType.Character, + field: 'cultivationCount', + count: 1 + }); const exp = this.getAddExp(); const levelPrecent = Math.round(this.envSrv.maxExp / Object.keys(this.envSrv.levelMap).length); const newExp = exp + this.levelInfo.exp; diff --git a/src/app/services/statistics.service.spec.ts b/src/app/services/statistics.service.spec.ts new file mode 100644 index 0000000..2df0af3 --- /dev/null +++ b/src/app/services/statistics.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { StatisticsService } from './statistics.service'; + +describe('StatisticsService', () => { + let service: StatisticsService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(StatisticsService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/statistics.service.ts b/src/app/services/statistics.service.ts new file mode 100644 index 0000000..ca286ea --- /dev/null +++ b/src/app/services/statistics.service.ts @@ -0,0 +1,31 @@ +import { Injectable, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; + +import { CharacterStatistics, StatisticsEvent, StatisticsEventType } from '../models'; + +@Injectable({ + providedIn: 'root' +}) +export class StatisticsService { + characterStatistics: CharacterStatistics = { + cultivationCount: 0 + }; + statistics: Subject = new Subject(); + statistics$ = this.statistics.asObservable(); + + update(event: StatisticsEvent) { + switch (event.type) { + case StatisticsEventType.Character: + (this.characterStatistics as any)[event.field] += event.count; + break; + } + this.statistics.next(event); + } + + getValue(type: StatisticsEventType, field: string) { + switch (type) { + case StatisticsEventType.Character: + return (this.characterStatistics as any)[field]; + } + } +} diff --git a/src/app/services/task.service.ts b/src/app/services/task.service.ts index 1cc0e0e..76719d9 100644 --- a/src/app/services/task.service.ts +++ b/src/app/services/task.service.ts @@ -1,7 +1,8 @@ -import { Injectable } from '@angular/core'; -import { Subject } from 'rxjs'; +import { inject, Injectable } from '@angular/core'; +import { Subject, Subscription } from 'rxjs'; -import { Task, TASKS } from '../models'; +import { StatisticsEventType, Task, TASKS } from '../models'; +import { StatisticsService } from './statistics.service'; @Injectable({ providedIn: 'root'