poi-plugin-kai-planner 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -20
- package/package.json +1 -1
- package/src/app/tabs/wishlist/WishlistTab.js +34 -2
- package/src/data/loaders/loadStaticData.js +4 -2
- package/src/data/static/data_manifest.json +49 -3
- package/src/data/static/equip_base_cost.json +2508 -5000
- package/src/data/static/equipment_upgrade_path.json +3449 -3555
- package/src/data/static/improvement_arrangement.json +13362 -15677
- package/src/data/static/improvement_consume_item.json +6338 -8933
- package/src/data/static/improvement_consume_step.json +6446 -9284
- package/src/data/static/improvement_upgrade_cost.json +3170 -4766
- package/src/data/static/improvement_upgrade_target.json +2031 -2640
- package/src/data/static/material.json +44 -88
- package/src/services/common/secretaryDisplay.js +50 -42
- package/src/services/wishlist/buildWishlistViewModel.js +17 -2
package/README.md
CHANGED
|
@@ -1,35 +1,33 @@
|
|
|
1
1
|
# poi-plugin-kai-planner
|
|
2
2
|
|
|
3
|
-
用于 POI
|
|
3
|
+
用于 POI 的改修规划插件,包含“每日改修”和“改修心愿清单”两条主链路。
|
|
4
4
|
|
|
5
|
-
## 当前发布机制(2026-
|
|
5
|
+
## 当前发布机制(2026-03)
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- 玩家安装方式:通过 npm 安装
|
|
9
|
-
- 远端静态数据:独立公开仓库 `PlannerRemoteRawData
|
|
10
|
-
- 调试页开关:`package.json -> poiPlugin.enableDebug
|
|
11
|
-
-
|
|
12
|
-
- `package.json.files` 白名单
|
|
13
|
-
- `.npmignore` 保险排除
|
|
14
|
-
- `npm run release:check` 发版前检查
|
|
7
|
+
- 插件代码仓库:本仓库(私有)
|
|
8
|
+
- 玩家安装方式:通过 npm 安装 POI 插件包
|
|
9
|
+
- 远端静态数据:独立公开仓库 `PlannerRemoteRawData`
|
|
10
|
+
- 调试页开关:`package.json -> poiPlugin.enableDebug`,发布建议关闭
|
|
11
|
+
- 发布包控制:`package.json.files` + `.npmignore` + `npm run release:check`
|
|
15
12
|
|
|
16
13
|
## 功能概览
|
|
17
14
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
15
|
+
- 每日改修:按 JST(GMT+9)展示当天可改修/可进化项目、秘书舰与基础消耗
|
|
16
|
+
- 改修心愿清单:创建计划、跟踪实时进度、查看今日下一步、缺口与起点绑定状态
|
|
17
|
+
- 心愿清单表格已拆分为两个 tab:
|
|
18
|
+
- `改修未完成`:默认 tab,只展示仍有剩余步骤的计划
|
|
19
|
+
- `改修已完成`:只展示 `remainingSteps.length === 0` 的计划
|
|
20
|
+
- 心愿清单支持行内编辑:优先级、目标星级、起点重绑、展开查看实时缺口
|
|
21
|
+
- Debug:可选加载,不影响 Daily/Wishlist 主流程
|
|
24
22
|
|
|
25
23
|
## 本地数据
|
|
26
24
|
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
- 文件存储不可用时回退 `localStorage`(`kai_planner_user_plans_v1`)。
|
|
25
|
+
- 用户计划优先写入:`runtime_data/userPlans/plans.v1.json`
|
|
26
|
+
- 文件存储不可用时回退 `localStorage`:`kai_planner_user_plans_v1`
|
|
30
27
|
- 远端静态数据缓存:
|
|
31
28
|
- `runtime_data/static_data/meta.json`
|
|
32
29
|
- `runtime_data/static_data/cache/*.json`
|
|
30
|
+
- bundled 静态数据基线:`src/data/static/*.json`
|
|
33
31
|
|
|
34
32
|
## 常用命令
|
|
35
33
|
|
|
@@ -42,7 +40,7 @@
|
|
|
42
40
|
- 架构说明:[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
|
|
43
41
|
- 数据版本策略:[docs/DATA_VERSIONING.md](docs/DATA_VERSIONING.md)
|
|
44
42
|
- 计划存储策略:[docs/STORAGE_POLICY.md](docs/STORAGE_POLICY.md)
|
|
45
|
-
- Wishlist
|
|
43
|
+
- Wishlist 状态字段:[docs/WISHLIST_STATE_FIELDS.md](docs/WISHLIST_STATE_FIELDS.md)
|
|
46
44
|
- npm/POI 发布流程:[docs/RELEASE_POI_NPM.md](docs/RELEASE_POI_NPM.md)
|
|
47
45
|
- 私有仓库更新流程:[docs/PRIVATE_REPO_UPDATE.md](docs/PRIVATE_REPO_UPDATE.md)
|
|
48
46
|
- 远端静态数据更新流程:[docs/REMOTE_DATA_UPDATE.md](docs/REMOTE_DATA_UPDATE.md)
|
package/package.json
CHANGED
|
@@ -107,6 +107,7 @@ class WishlistTab extends React.Component {
|
|
|
107
107
|
rebindInputById: {},
|
|
108
108
|
editById: {},
|
|
109
109
|
filterTargetName: "",
|
|
110
|
+
activePlanTab: "unfinished",
|
|
110
111
|
showCreateForm: false,
|
|
111
112
|
create: {
|
|
112
113
|
targetEquipId: "",
|
|
@@ -602,7 +603,16 @@ class WishlistTab extends React.Component {
|
|
|
602
603
|
width: 240,
|
|
603
604
|
};
|
|
604
605
|
const th = { textAlign: "left", padding: "10px 10px", borderBottom: "1px solid rgba(255,255,255,0.12)" };
|
|
605
|
-
const td = { padding: "10px 10px", borderBottom: "1px solid rgba(255,255,255,0.08)", verticalAlign: "top" };
|
|
606
|
+
const td = { padding: "10px 10px", borderBottom: "1px solid rgba(255,255,255,0.08)", verticalAlign: "top" };
|
|
607
|
+
const planTabBar = { display: "flex", gap: 8, marginTop: 10, flexWrap: "wrap" };
|
|
608
|
+
const planTabStyle = (active) => ({
|
|
609
|
+
padding: "6px 10px",
|
|
610
|
+
borderRadius: 8,
|
|
611
|
+
border: "1px solid rgba(255,255,255,0.12)",
|
|
612
|
+
background: active ? "rgba(255,255,255,0.14)" : "transparent",
|
|
613
|
+
color: "#e5e7eb",
|
|
614
|
+
cursor: "pointer",
|
|
615
|
+
});
|
|
606
616
|
|
|
607
617
|
if (!state || !state.const || !state.info) {
|
|
608
618
|
return React.createElement("pre", null, this.state.error || "Redux state unavailable.");
|
|
@@ -617,6 +627,8 @@ class WishlistTab extends React.Component {
|
|
|
617
627
|
getEquipSortno,
|
|
618
628
|
masterEquipsById,
|
|
619
629
|
});
|
|
630
|
+
const activePlanTab = this.state.activePlanTab || "unfinished";
|
|
631
|
+
const activeRows = activePlanTab === "completed" ? vm.completedRows : vm.unfinishedRows;
|
|
620
632
|
|
|
621
633
|
return React.createElement(
|
|
622
634
|
"div",
|
|
@@ -643,6 +655,26 @@ class WishlistTab extends React.Component {
|
|
|
643
655
|
React.createElement("button", { onClick: () => this.setState({ showCreateForm: true }) }, "新增改修计划"),
|
|
644
656
|
React.createElement("button", { onClick: this.refreshPlans }, "刷新")
|
|
645
657
|
),
|
|
658
|
+
React.createElement(
|
|
659
|
+
"div",
|
|
660
|
+
{ style: planTabBar },
|
|
661
|
+
React.createElement(
|
|
662
|
+
"button",
|
|
663
|
+
{
|
|
664
|
+
style: planTabStyle(activePlanTab === "unfinished"),
|
|
665
|
+
onClick: () => this.setState({ activePlanTab: "unfinished" }),
|
|
666
|
+
},
|
|
667
|
+
`改修未完成 (${vm.counts.unfinished})`
|
|
668
|
+
),
|
|
669
|
+
React.createElement(
|
|
670
|
+
"button",
|
|
671
|
+
{
|
|
672
|
+
style: planTabStyle(activePlanTab === "completed"),
|
|
673
|
+
onClick: () => this.setState({ activePlanTab: "completed" }),
|
|
674
|
+
},
|
|
675
|
+
`改修已完成 (${vm.counts.completed})`
|
|
676
|
+
)
|
|
677
|
+
),
|
|
646
678
|
this.renderCreateForm(state, plans),
|
|
647
679
|
Object.values(this.state.editById || {}).some((x) => x && x.error)
|
|
648
680
|
? React.createElement(
|
|
@@ -660,7 +692,7 @@ class WishlistTab extends React.Component {
|
|
|
660
692
|
"div",
|
|
661
693
|
{ style: bottom },
|
|
662
694
|
React.createElement(WishlistTable, {
|
|
663
|
-
rows:
|
|
695
|
+
rows: activeRows,
|
|
664
696
|
expandedById: this.state.expandedById,
|
|
665
697
|
rebindInputById: this.state.rebindInputById,
|
|
666
698
|
editById: this.state.editById,
|
|
@@ -67,7 +67,7 @@ function loadStaticData() {
|
|
|
67
67
|
const improvementArrangement = (improvementArrangement2 || []).map((r) => ({
|
|
68
68
|
...r,
|
|
69
69
|
equipment_id: toInt(r.equipment_id),
|
|
70
|
-
secretary_id: toInt(r.secretary_id),
|
|
70
|
+
secretary_id: r.secretary_id == null ? null : toInt(r.secretary_id),
|
|
71
71
|
monday: normalizeBool(r.monday),
|
|
72
72
|
tuesday: normalizeBool(r.tuesday),
|
|
73
73
|
wednesday: normalizeBool(r.wednesday),
|
|
@@ -78,6 +78,7 @@ function loadStaticData() {
|
|
|
78
78
|
note: r.note == null ? null : String(r.note),
|
|
79
79
|
is_deleted: normalizeBool(r.is_deleted),
|
|
80
80
|
secretary_variant: r.secretary_variant == null ? null : String(r.secretary_variant),
|
|
81
|
+
secretary_label: r.secretary_label == null ? null : String(r.secretary_label),
|
|
81
82
|
route_kind: r.route_kind == null || r.route_kind === "" ? null : String(r.route_kind),
|
|
82
83
|
}));
|
|
83
84
|
|
|
@@ -95,7 +96,8 @@ function loadStaticData() {
|
|
|
95
96
|
|
|
96
97
|
const improvementConsumeItem = (improvementConsumeItem2 || []).map((r) => ({
|
|
97
98
|
...r,
|
|
98
|
-
|
|
99
|
+
id: r.id == null ? (r.uuid == null ? null : String(r.uuid)) : String(r.id),
|
|
100
|
+
uuid: r.uuid == null ? (r.id == null ? null : String(r.id)) : String(r.uuid),
|
|
99
101
|
step_id: r.step_id == null ? null : String(r.step_id),
|
|
100
102
|
item_equipment_id: r.item_equipment_id == null ? null : toInt(r.item_equipment_id),
|
|
101
103
|
item_material_key: r.item_material_key == null ? null : String(r.item_material_key),
|
|
@@ -1,7 +1,53 @@
|
|
|
1
1
|
{
|
|
2
|
-
"data_version": "2026.
|
|
3
|
-
"
|
|
4
|
-
"
|
|
2
|
+
"data_version": "2026.03.08",
|
|
3
|
+
"run_date": "2026-03-08",
|
|
4
|
+
"updated_at": "2026-03-08T00:00:00+08:00",
|
|
5
|
+
"previous_snapshot": "2026-02-26",
|
|
6
|
+
"source": {
|
|
7
|
+
"repo": "yukikuri/akashi-list",
|
|
8
|
+
"ref": "gh-pages",
|
|
9
|
+
"detail_path": "detail/"
|
|
10
|
+
},
|
|
11
|
+
"target_equipment_ids": [
|
|
12
|
+
2,
|
|
13
|
+
3,
|
|
14
|
+
4,
|
|
15
|
+
6,
|
|
16
|
+
14,
|
|
17
|
+
15,
|
|
18
|
+
28,
|
|
19
|
+
44,
|
|
20
|
+
69,
|
|
21
|
+
70,
|
|
22
|
+
90,
|
|
23
|
+
93,
|
|
24
|
+
94,
|
|
25
|
+
99,
|
|
26
|
+
102,
|
|
27
|
+
199,
|
|
28
|
+
200,
|
|
29
|
+
221,
|
|
30
|
+
260,
|
|
31
|
+
261,
|
|
32
|
+
266,
|
|
33
|
+
267,
|
|
34
|
+
313,
|
|
35
|
+
324,
|
|
36
|
+
325,
|
|
37
|
+
326,
|
|
38
|
+
327,
|
|
39
|
+
356,
|
|
40
|
+
357,
|
|
41
|
+
372,
|
|
42
|
+
451,
|
|
43
|
+
489,
|
|
44
|
+
491,
|
|
45
|
+
547,
|
|
46
|
+
548,
|
|
47
|
+
549,
|
|
48
|
+
570,
|
|
49
|
+
571
|
|
50
|
+
],
|
|
5
51
|
"files": [
|
|
6
52
|
"equip_base_cost.json",
|
|
7
53
|
"equipment_upgrade_path.json",
|