poi-plugin-kai-planner 1.0.4 → 1.0.6

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 CHANGED
@@ -1,48 +1,54 @@
1
- # poi-plugin-kai-planner
2
-
3
- 用于 POI 的改修规划插件,包含“每日改修”和“改修心愿清单”两条主链路。
4
-
5
- ## 当前发布机制(2026-03)
6
-
7
- - 插件代码仓库:本仓库(私有)
8
- - 玩家安装方式:通过 npm 安装 POI 插件包
9
- - 远端静态数据:独立公开仓库 `PlannerRemoteRawData`
10
- - 调试页开关:`package.json -> poiPlugin.enableDebug`,发布建议关闭
11
- - 发布包控制:`package.json.files` + `.npmignore` + `npm run release:check`
12
-
13
- ## 功能概览
14
-
15
- - 每日改修:按 JST(GMT+9)展示当天可改修/可进化项目、秘书舰与基础消耗
16
- - 改修心愿清单:创建计划、跟踪实时进度、查看今日下一步、缺口与起点绑定状态
17
- - 心愿清单表格已拆分为两个 tab:
18
- - `改修未完成`:默认 tab,只展示仍有剩余步骤的计划
19
- - `改修已完成`:只展示 `remainingSteps.length === 0` 的计划
20
- - 心愿清单支持行内编辑:优先级、目标星级、起点重绑、展开查看实时缺口
21
- - Debug:可选加载,不影响 Daily/Wishlist 主流程
22
-
23
- ## 本地数据
24
-
25
- - 用户计划优先写入:
26
- - 若 Electron 可提供 `userData` 目录,则写入 `<userData>/poi-plugin-kai-planner/userPlans/plans.v1.json`
27
- - 若无法获取稳定用户目录,则回退到 `<plugin_root>/runtime_data/userPlans/plans.v1.json`
28
- - 文件存储不可用时回退 `localStorage`:`kai_planner_user_plans_v1`
29
- - 远端静态数据缓存:
30
- - `runtime_data/static_data/meta.json`
31
- - `runtime_data/static_data/cache/*.json`
32
- - bundled 静态数据基线:`src/data/static/*.json`
33
-
34
- ## 常用命令
35
-
36
- - `npm test`
37
- - `npm run release:check`
38
- - `npm run release:pack`
39
-
40
- ## 文档导航
41
-
42
- - 架构说明:[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
43
- - 数据版本策略:[docs/DATA_VERSIONING.md](docs/DATA_VERSIONING.md)
44
- - 计划存储策略:[docs/STORAGE_POLICY.md](docs/STORAGE_POLICY.md)
45
- - Wishlist 状态字段:[docs/WISHLIST_STATE_FIELDS.md](docs/WISHLIST_STATE_FIELDS.md)
46
- - npm/POI 发布流程:[docs/RELEASE_POI_NPM.md](docs/RELEASE_POI_NPM.md)
47
- - 私有仓库更新流程:[docs/PRIVATE_REPO_UPDATE.md](docs/PRIVATE_REPO_UPDATE.md)
1
+ # poi-plugin-kai-planner
2
+
3
+ 用于 POI 的改修规划插件,包含“每日改修”和“改修心愿清单”两条主链路。
4
+
5
+ ## 当前发布机制(2026-03)
6
+
7
+ - 插件代码仓库:本仓库(私有)
8
+ - 玩家安装方式:通过 npm 安装 POI 插件包
9
+ - 远端静态数据:独立公开仓库 `PlannerRemoteRawData`
10
+ - 调试页开关:`package.json -> poiPlugin.enableDebug`,发布建议关闭
11
+ - 发布包控制:`package.json.files` + `.npmignore` + `npm run release:check`
12
+
13
+ ## 功能概览
14
+
15
+ - 每日改修:按 JST(GMT+9)展示当天可改修/可进化项目、秘书舰与基础消耗
16
+ - 改修心愿清单:创建计划、跟踪实时进度、查看今日下一步、缺口与起点绑定状态
17
+ - 心愿清单表格已拆分为两个 tab:
18
+ - `改修未完成`:默认 tab,只展示仍有剩余步骤的计划
19
+ - `改修已完成`:只展示 `remainingSteps.length === 0` 的计划
20
+ - 心愿清单支持行内编辑:优先级、目标星级、起点重绑、展开查看实时缺口
21
+ - Debug:可选加载,不影响 Daily/Wishlist 主流程
22
+
23
+ ## 本地数据
24
+
25
+ - 用户计划优先写入:
26
+ - 若 Electron 可提供 `userData` 目录,则写入 `<userData>/poi-plugin-kai-planner/userPlans/plans.v1.json`
27
+ - 若无法获取稳定用户目录,则回退到 `<plugin_root>/runtime_data/userPlans/plans.v1.json`
28
+ - 文件存储不可用时回退 `localStorage`:`kai_planner_user_plans_v1`
29
+ - 远端静态数据缓存:
30
+ - `runtime_data/static_data/meta.json`
31
+ - `runtime_data/static_data/cache/*.json`
32
+ - bundled 静态数据基线:`src/data/static/*.json`
33
+
34
+ ## 常用命令
35
+
36
+ - `npm test`
37
+ - `npm run release:check`
38
+ - `npm run release:pack`
39
+
40
+ ## 文档导航
41
+
42
+ - 架构说明:[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
43
+ - 数据版本策略:[docs/DATA_VERSIONING.md](docs/DATA_VERSIONING.md)
44
+ - 计划存储策略:[docs/STORAGE_POLICY.md](docs/STORAGE_POLICY.md)
45
+ - Wishlist 状态字段:[docs/WISHLIST_STATE_FIELDS.md](docs/WISHLIST_STATE_FIELDS.md)
46
+ - npm/POI 发布流程:[docs/RELEASE_POI_NPM.md](docs/RELEASE_POI_NPM.md)
47
+ - 私有仓库更新流程:[docs/PRIVATE_REPO_UPDATE.md](docs/PRIVATE_REPO_UPDATE.md)
48
48
  - 远端静态数据更新流程:[docs/REMOTE_DATA_UPDATE.md](docs/REMOTE_DATA_UPDATE.md)
49
+
50
+ ## 2026-03 UI 更新
51
+ - Daily 页面支持按装备类型筛选;类型名来自 POI 的 `$equipTypes[api_type[3]].api_name`
52
+ - Daily 与 Wishlist 表格中的装备名称前都会显示装备类型 icon
53
+ - Wishlist 主表中的优先级改为标签样式展示(P0-P5 固定颜色)
54
+ - Wishlist 展开明细中的“当前持有”计数会去除改修星数大于 0 的装备以及计划起点装备
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poi-plugin-kai-planner",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "main": "index.js",
5
5
  "author": "aulu",
6
6
  "contributors": ["aulu"],
@@ -0,0 +1,30 @@
1
+ /* src/app/components/SlotitemTypeIcon.js */
2
+
3
+ const React = require("react");
4
+
5
+ let SlotitemIcon = null;
6
+ try {
7
+ ({ SlotitemIcon } = require("views/components/etc/icon"));
8
+ } catch {}
9
+
10
+ function SlotitemTypeIcon({ iconType, title, style }) {
11
+ if (!iconType || !SlotitemIcon) return null;
12
+ return React.createElement(
13
+ "span",
14
+ {
15
+ title: title || "",
16
+ style: {
17
+ display: "inline-flex",
18
+ alignItems: "center",
19
+ justifyContent: "center",
20
+ width: 20,
21
+ height: 20,
22
+ flexShrink: 0,
23
+ ...(style || {}),
24
+ },
25
+ },
26
+ React.createElement(SlotitemIcon, { slotitemId: iconType })
27
+ );
28
+ }
29
+
30
+ module.exports = { SlotitemTypeIcon };
@@ -1,17 +1,18 @@
1
1
  /* src/app/tabs/daily/DailyTab.js */
2
2
 
3
- const React = require("react");
4
-
5
- const { loadStaticData } = require("../../../data/loaders/loadStaticData");
6
- const { buildArrangementIndex } = require("../../../data/indexes/buildArrangementIndex");
7
- const { buildDailyViewModel } = require("../../../services/daily/buildDailyViewModel");
8
- const { getReduxStateFromEnvWindow } = require("../../../services/player/getReduxStateFromEnvWindow");
9
- const {
10
- TOKYO_WEEK_KEYS,
11
- TOKYO_WEEK_LABEL_ZH,
12
- formatTokyoDateTimeWithWeekday,
13
- getTokyoWeekdayKey,
14
- } = require("../../../services/utils/tokyoTime");
3
+ const React = require("react");
4
+ const { SlotitemTypeIcon } = require("../../components/SlotitemTypeIcon");
5
+
6
+ const { loadStaticData } = require("../../../data/loaders/loadStaticData");
7
+ const { buildArrangementIndex } = require("../../../data/indexes/buildArrangementIndex");
8
+ const { buildDailyViewModel } = require("../../../services/daily/buildDailyViewModel");
9
+ const { getReduxStateFromEnvWindow } = require("../../../services/player/getReduxStateFromEnvWindow");
10
+ const {
11
+ TOKYO_WEEK_KEYS,
12
+ TOKYO_WEEK_LABEL_ZH,
13
+ formatTokyoDateTimeWithWeekday,
14
+ getTokyoWeekdayKey,
15
+ } = require("../../../services/utils/tokyoTime");
15
16
 
16
17
  function buildShipIndexes(masterShipsRaw) {
17
18
  const shipBySortno = {};
@@ -38,46 +39,41 @@ function ItemList({ title, items }) {
38
39
  React.createElement(
39
40
  "ul",
40
41
  { style: { margin: 0, paddingLeft: 18 } },
41
- items.map((it, idx) =>
42
- React.createElement("li", { key: idx }, `${it.name} × ${it.count}`)
43
- )
42
+ items.map((it, idx) => React.createElement("li", { key: idx }, `${it.name} × ${it.count}`))
44
43
  )
45
44
  );
46
45
  }
47
46
 
48
47
  function PhaseBlock({ phase }) {
49
- const label = phase.phase === 0 ? "阶段0(0→1…5→6)" : "阶段1(6→7…9→MAX)";
48
+ const label = phase.phase === 0 ? "阶段0(0 -> 6)" : "阶段1(6 -> MAX)";
50
49
  const dev = phase.dev || { min: 0, max: 0 };
51
50
  const screw = phase.screw || { min: 0, max: 0 };
52
-
53
- const extras = (phase.items && phase.items.extras) ? phase.items.extras : [];
51
+ const extras = phase.items && phase.items.extras ? phase.items.extras : [];
54
52
 
55
53
  return React.createElement(
56
54
  "div",
57
55
  { style: { border: "1px solid rgba(255,255,255,0.12)", borderRadius: 8, padding: 10, marginTop: 10 } },
58
- React.createElement("div", { style: { display: "flex", justifyContent: "space-between", gap: 12, flexWrap: "wrap" } },
56
+ React.createElement(
57
+ "div",
58
+ { style: { display: "flex", justifyContent: "space-between", gap: 12, flexWrap: "wrap" } },
59
59
  React.createElement("div", { style: { fontWeight: 800 } }, label),
60
- React.createElement("div", { style: { opacity: 0.9 } },
61
- `资材(开发): ${dev.min}/${dev.max},螺丝: ${screw.min}/${screw.max}`
62
- )
60
+ React.createElement("div", { style: { opacity: 0.9 } }, `资材(开发): ${dev.min}/${dev.max},螺丝: ${screw.min}/${screw.max}`)
63
61
  ),
64
62
  ItemList({ title: "通用消耗(每次)", items: phase.items ? phase.items.common : [] }),
65
63
  extras.length > 0
66
64
  ? React.createElement(
67
65
  "div",
68
66
  { style: { marginTop: 6 } },
69
- React.createElement("div", { style: { opacity: 0.85, marginBottom: 4 } }, "独立消耗(特定星级区间,叠加在通用消耗上)"),
67
+ React.createElement("div", { style: { opacity: 0.85, marginBottom: 4 } }, "额外消耗(特定星级区间,会叠加在通用消耗上)"),
70
68
  extras.map((ex, i) =>
71
69
  React.createElement(
72
70
  "div",
73
71
  { key: i, style: { marginTop: 6, padding: "8px 10px", background: "rgba(255,255,255,0.05)", borderRadius: 8 } },
74
- React.createElement("div", { style: { fontWeight: 700, marginBottom: 4 } }, `${ex.star_from}→${ex.star_to}`),
72
+ React.createElement("div", { style: { fontWeight: 700, marginBottom: 4 } }, `${ex.star_from} -> ${ex.star_to}`),
75
73
  React.createElement(
76
74
  "ul",
77
75
  { style: { margin: 0, paddingLeft: 18 } },
78
- (ex.items || []).map((it, idx) =>
79
- React.createElement("li", { key: idx }, `${it.name} × ${it.count}`)
80
- )
76
+ (ex.items || []).map((it, idx) => React.createElement("li", { key: idx }, `${it.name} × ${it.count}`))
81
77
  )
82
78
  )
83
79
  )
@@ -88,19 +84,11 @@ function PhaseBlock({ phase }) {
88
84
 
89
85
  function UpgradeBlock({ upgrades, upgradeMeta }) {
90
86
  if (!upgradeMeta || upgradeMeta.hasAnyUpgradeConfig === false) {
91
- return React.createElement(
92
- "div",
93
- { style: { marginTop: 10, opacity: 0.8 } },
94
- "该装备【任意日子都不可进化】(没有进化配置)"
95
- );
87
+ return React.createElement("div", { style: { marginTop: 10, opacity: 0.8 } }, "该装备任意日期都不可进化(没有进化配置)");
96
88
  }
97
89
 
98
90
  if (!upgrades || upgrades.length === 0) {
99
- return React.createElement(
100
- "div",
101
- { style: { marginTop: 10, opacity: 0.8 } },
102
- "该装备【今天不可进化】(今日可用秘书舰不符合进化要求)"
103
- );
91
+ return React.createElement("div", { style: { marginTop: 10, opacity: 0.8 } }, "该装备今天不可进化(今日可用秘书舰不符合进化要求)");
104
92
  }
105
93
 
106
94
  return React.createElement(
@@ -110,16 +98,18 @@ function UpgradeBlock({ upgrades, upgradeMeta }) {
110
98
  React.createElement(
111
99
  "div",
112
100
  { key: idx, style: { border: "1px solid rgba(255,255,255,0.12)", borderRadius: 8, padding: 10, marginTop: 10 } },
113
- React.createElement("div", { style: { display: "flex", justifyContent: "space-between", gap: 12, flexWrap: "wrap" } },
114
- React.createElement("div", { style: { fontWeight: 900 } }, `进化:→ ${u.upgradeName}(${u.upgradeId})`),
115
- React.createElement("div", { style: { opacity: 0.9 } }, `资材(开发): ${u.dev.min}/${u.dev.max},螺丝: ${u.screw.min}/${u.screw.max}`)
116
- ),
117
- React.createElement("div", { style: { marginTop: 6, opacity: 0.9 } }, `指定秘书舰(今日可用):${u.secretaryText || "不可"}`),
118
- ItemList({ title: "进化消耗", items: u.items || [] })
119
- )
120
- )
121
- );
122
- }
101
+ React.createElement(
102
+ "div",
103
+ { style: { display: "flex", justifyContent: "space-between", gap: 12, flexWrap: "wrap" } },
104
+ React.createElement("div", { style: { fontWeight: 900 } }, `进化:→ ${u.upgradeName}(${u.upgradeId})`),
105
+ React.createElement("div", { style: { opacity: 0.9 } }, `资材(开发): ${u.dev.min}/${u.dev.max},螺丝: ${u.screw.min}/${u.screw.max}`)
106
+ ),
107
+ React.createElement("div", { style: { marginTop: 6, opacity: 0.9 } }, `指定秘书舰(今日可用):${u.secretaryText || "不可"}`),
108
+ ItemList({ title: "进化消耗", items: u.items || [] })
109
+ )
110
+ )
111
+ );
112
+ }
123
113
 
124
114
  function upgradeStatusText(upgradeMeta) {
125
115
  if (!upgradeMeta || upgradeMeta.hasAnyUpgradeConfig === false) return "不可进化";
@@ -127,16 +117,17 @@ function upgradeStatusText(upgradeMeta) {
127
117
  return "今日不可进化";
128
118
  }
129
119
 
130
- class DailyTab extends React.Component {
131
- constructor(props) {
132
- super(props);
133
- this.state = {
134
- tokyoText: formatTokyoDateTimeWithWeekday(),
135
- weekdayKey: getTokyoWeekdayKey(),
136
- expanded: {}, // equipId -> bool
137
- vm: null,
138
- error: null,
120
+ class DailyTab extends React.Component {
121
+ constructor(props) {
122
+ super(props);
123
+ this.state = {
124
+ tokyoText: formatTokyoDateTimeWithWeekday(),
125
+ weekdayKey: getTokyoWeekdayKey(),
126
+ expanded: {},
127
+ vm: null,
128
+ error: null,
139
129
  search: "",
130
+ searchEquipType: "",
140
131
  };
141
132
 
142
133
  this.refresh = this.refresh.bind(this);
@@ -144,12 +135,12 @@ class DailyTab extends React.Component {
144
135
  this.toggleRow = this.toggleRow.bind(this);
145
136
  }
146
137
 
147
- componentDidMount() {
148
- this.refresh();
149
- this._timer = setInterval(() => {
150
- this.setState({ tokyoText: formatTokyoDateTimeWithWeekday() });
151
- }, 1000);
152
- }
138
+ componentDidMount() {
139
+ this.refresh();
140
+ this._timer = setInterval(() => {
141
+ this.setState({ tokyoText: formatTokyoDateTimeWithWeekday() });
142
+ }, 1000);
143
+ }
153
144
 
154
145
  componentWillUnmount() {
155
146
  if (this._timer) clearInterval(this._timer);
@@ -181,13 +172,14 @@ class DailyTab extends React.Component {
181
172
  }
182
173
 
183
174
  const masterEquipsById = state.const.$equips || {};
175
+ const masterEquipTypesById = state.const.$equipTypes || {};
184
176
  const masterShipsRaw = state.const.$ships || {};
185
177
  const { shipBySortno, shipByApiId } = buildShipIndexes(masterShipsRaw);
186
178
 
187
179
  const vm = buildDailyViewModel({
188
180
  staticData,
189
181
  arrangementIndex,
190
- poi: { masterEquipsById, shipBySortno, shipByApiId },
182
+ poi: { masterEquipsById, masterEquipTypesById, shipBySortno, shipByApiId },
191
183
  weekdayKey: this.state.weekdayKey,
192
184
  });
193
185
 
@@ -204,7 +196,7 @@ class DailyTab extends React.Component {
204
196
  flexDirection: "column",
205
197
  color: "#e5e7eb",
206
198
  fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial",
207
- fontSize: 12,
199
+ fontSize: 14,
208
200
  lineHeight: 1.4,
209
201
  };
210
202
 
@@ -228,7 +220,6 @@ class DailyTab extends React.Component {
228
220
  cursor: "pointer",
229
221
  userSelect: "none",
230
222
  });
231
-
232
223
  const toolbarStyle = { display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" };
233
224
 
234
225
  const inputStyle = {
@@ -239,6 +230,7 @@ class DailyTab extends React.Component {
239
230
  background: "rgba(0,0,0,0.15)",
240
231
  color: "#e5e7eb",
241
232
  outline: "none",
233
+ fontSize: 14,
242
234
  };
243
235
 
244
236
  const scrollAreaStyle = {
@@ -262,78 +254,114 @@ class DailyTab extends React.Component {
262
254
  const smallMuted = { opacity: 0.75, fontSize: 11 };
263
255
 
264
256
  const vm = this.state.vm;
265
- const q = (this.state.search || "").trim().toLowerCase();
266
- const rows = vm && vm.rows ? (q ? vm.rows.filter((r) => (r.equipName || "").toLowerCase().includes(q)) : vm.rows) : [];
257
+ const q = String(this.state.search || "").trim().toLowerCase();
258
+ const selectedEquipType = String(this.state.searchEquipType || "").trim();
259
+ const allRows = vm && vm.rows ? vm.rows : [];
260
+ const equipTypeOptions = [];
261
+ const seenEquipTypes = new Set();
262
+ for (const row of allRows) {
263
+ const name = String(row && row.equipTypeName ? row.equipTypeName : "").trim();
264
+ if (!name || seenEquipTypes.has(name)) continue;
265
+ seenEquipTypes.add(name);
266
+ equipTypeOptions.push(name);
267
+ }
268
+ const rows = allRows.filter((r) => {
269
+ if (selectedEquipType && String(r.equipTypeName || "") !== selectedEquipType) return false;
270
+ if (q && !String(r.equipName || "").toLowerCase().includes(q)) return false;
271
+ return true;
272
+ });
267
273
 
268
274
  return React.createElement(
269
275
  "div",
270
276
  { style: wrapperStyle },
271
-
272
277
  React.createElement(
273
278
  "div",
274
279
  { style: stickyHeaderStyle },
275
280
  React.createElement(
276
281
  "div",
277
282
  { style: headerRowStyle },
278
- React.createElement("div", null,
279
- React.createElement("div", { style: { fontSize: 16, fontWeight: 900 } }, "每日改修"),
283
+ React.createElement(
284
+ "div",
285
+ null,
286
+ React.createElement("div", { style: { fontSize: 18, fontWeight: 900 } }, "每日改修"),
280
287
  React.createElement("div", { style: smallMuted }, `当前时间(GMT+9):${this.state.tokyoText}`)
281
288
  ),
282
- React.createElement("div", { style: toolbarStyle },
289
+ React.createElement(
290
+ "div",
291
+ { style: toolbarStyle },
292
+ React.createElement(
293
+ "select",
294
+ {
295
+ value: this.state.searchEquipType,
296
+ onChange: (e) => this.setState({ searchEquipType: e.target.value }),
297
+ style: { ...inputStyle, width: 180 },
298
+ },
299
+ React.createElement("option", { value: "" }, "全部类型"),
300
+ ...equipTypeOptions.map((name) => React.createElement("option", { key: name, value: name }, name))
301
+ ),
283
302
  React.createElement("input", {
284
303
  value: this.state.search,
285
304
  placeholder: "搜索装备名称...",
286
305
  onChange: (e) => this.setState({ search: e.target.value }),
287
306
  style: inputStyle,
288
307
  }),
289
- React.createElement("button", { onClick: this.refresh }, "Refresh")
308
+ React.createElement("button", { onClick: this.refresh }, "刷新")
290
309
  )
291
310
  ),
292
-
293
311
  React.createElement(
294
312
  "div",
295
313
  { style: tabBarStyle },
296
- TOKYO_WEEK_KEYS.slice(1).map((k) =>
297
- React.createElement("div", {
298
- key: k,
299
- style: tabStyle(this.state.weekdayKey === k),
300
- onClick: () => this.setWeekday(k),
301
- }, TOKYO_WEEK_LABEL_ZH[k])
302
- ),
303
- React.createElement("div", {
304
- key: "sunday",
305
- style: tabStyle(this.state.weekdayKey === "sunday"),
306
- onClick: () => this.setWeekday("sunday"),
307
- }, TOKYO_WEEK_LABEL_ZH["sunday"])
308
- )
309
- ),
310
-
314
+ TOKYO_WEEK_KEYS.slice(1).map((k) =>
315
+ React.createElement(
316
+ "div",
317
+ {
318
+ key: k,
319
+ style: tabStyle(this.state.weekdayKey === k),
320
+ onClick: () => this.setWeekday(k),
321
+ },
322
+ TOKYO_WEEK_LABEL_ZH[k]
323
+ )
324
+ ),
325
+ React.createElement(
326
+ "div",
327
+ {
328
+ key: "sunday",
329
+ style: tabStyle(this.state.weekdayKey === "sunday"),
330
+ onClick: () => this.setWeekday("sunday"),
331
+ },
332
+ TOKYO_WEEK_LABEL_ZH.sunday
333
+ )
334
+ )
335
+ ),
311
336
  React.createElement(
312
337
  "div",
313
338
  { style: scrollAreaStyle },
314
-
315
339
  this.state.error
316
- ? React.createElement("pre", {
317
- style: {
318
- marginTop: 0,
319
- padding: 12,
320
- background: "#0b1220",
321
- border: "1px solid rgba(255,255,255,0.12)",
322
- borderRadius: 10,
323
- whiteSpace: "pre-wrap",
324
- wordBreak: "break-word",
325
- }
326
- }, this.state.error)
340
+ ? React.createElement(
341
+ "pre",
342
+ {
343
+ style: {
344
+ marginTop: 0,
345
+ padding: 12,
346
+ background: "#0b1220",
347
+ border: "1px solid rgba(255,255,255,0.12)",
348
+ borderRadius: 10,
349
+ whiteSpace: "pre-wrap",
350
+ wordBreak: "break-word",
351
+ },
352
+ },
353
+ this.state.error
354
+ )
327
355
  : null,
328
-
329
356
  !this.state.error && vm
330
357
  ? React.createElement(
331
358
  React.Fragment,
332
359
  null,
333
- React.createElement("div", { style: { margin: "0 0 10px", opacity: 0.8 } },
334
- `今日可改修装备:${rows.length} 条` + (q ? `(搜索:${this.state.search})` : "")
360
+ React.createElement(
361
+ "div",
362
+ { style: { margin: "0 0 10px", opacity: 0.8 } },
363
+ `今日可改修装备:${rows.length} 条${selectedEquipType ? `(类型:${selectedEquipType})` : ""}${q ? `(搜索:${this.state.search})` : ""}`
335
364
  ),
336
-
337
365
  React.createElement(
338
366
  "table",
339
367
  { style: tableStyle },
@@ -345,7 +373,7 @@ class DailyTab extends React.Component {
345
373
  null,
346
374
  React.createElement("th", { style: thStyle }, "装备名称"),
347
375
  React.createElement("th", { style: thStyle }, "基础消耗(油/弹/钢/铝)"),
348
- React.createElement("th", { style: thStyle }, `${TOKYO_WEEK_LABEL_ZH[this.state.weekdayKey]} - 秘书舰`),
376
+ React.createElement("th", { style: thStyle }, `${TOKYO_WEEK_LABEL_ZH[this.state.weekdayKey]} - 秘书舰`),
349
377
  React.createElement("th", { style: thStyle }, "可进化")
350
378
  )
351
379
  ),
@@ -356,14 +384,12 @@ class DailyTab extends React.Component {
356
384
  const exp = !!this.state.expanded[String(r.equipId)];
357
385
  const base = r.baseCost || {};
358
386
  const baseText = `${base.fuel || 0}/${base.ammo || 0}/${base.steel || 0}/${base.bauxite || 0}` + (base.missing ? "(缺数据)" : "");
359
- const icon = exp ? "" : "";
360
-
387
+ const foldIcon = exp ? "" : "?";
361
388
  const onRowClick = () => this.toggleRow(r.equipId);
362
389
 
363
390
  return React.createElement(
364
391
  React.Fragment,
365
392
  { key: r.equipId },
366
-
367
393
  React.createElement(
368
394
  "tr",
369
395
  {
@@ -371,12 +397,20 @@ class DailyTab extends React.Component {
371
397
  style: { cursor: "pointer" },
372
398
  title: "点击展开/收起",
373
399
  },
374
- React.createElement("td", { style: tdStyle },
375
- React.createElement("div", { style: { display: "flex", gap: 8, alignItems: "center" } },
400
+ React.createElement(
401
+ "td",
402
+ { style: tdStyle },
403
+ React.createElement(
404
+ "div",
405
+ { style: { display: "flex", gap: 8, alignItems: "center" } },
376
406
  React.createElement(
377
407
  "button",
378
408
  {
379
- onClick: (e) => { e.preventDefault(); e.stopPropagation(); onRowClick(); },
409
+ onClick: (e) => {
410
+ e.preventDefault();
411
+ e.stopPropagation();
412
+ onRowClick();
413
+ },
380
414
  style: {
381
415
  width: 28,
382
416
  height: 28,
@@ -388,10 +422,13 @@ class DailyTab extends React.Component {
388
422
  },
389
423
  title: "展开/收起",
390
424
  },
391
- icon
425
+ foldIcon
392
426
  ),
393
- React.createElement("div", null,
394
- React.createElement("div", { style: { fontWeight: 800 } }, r.equipName),
427
+ React.createElement(SlotitemTypeIcon, { iconType: r.iconType, title: r.equipTypeName }),
428
+ React.createElement(
429
+ "div",
430
+ null,
431
+ React.createElement("div", { style: { fontWeight: 400 } }, r.equipName),
395
432
  React.createElement("div", { style: smallMuted }, `equipId: ${r.equipId}`)
396
433
  )
397
434
  )
@@ -400,7 +437,6 @@ class DailyTab extends React.Component {
400
437
  React.createElement("td", { style: tdStyle }, r.secretaryText || "不可"),
401
438
  React.createElement("td", { style: tdStyle }, upgradeStatusText(r.upgradeMeta))
402
439
  ),
403
-
404
440
  exp
405
441
  ? React.createElement(
406
442
  "tr",
@@ -411,7 +447,6 @@ class DailyTab extends React.Component {
411
447
  React.createElement(SectionTitle, null, "改修消耗明细(每次)"),
412
448
  React.createElement(PhaseBlock, { phase: r.phases[0] }),
413
449
  React.createElement(PhaseBlock, { phase: r.phases[1] }),
414
-
415
450
  r.upgradeMeta && r.upgradeMeta.hasAnyUpgradeConfig
416
451
  ? React.createElement(
417
452
  React.Fragment,
@@ -436,4 +471,4 @@ class DailyTab extends React.Component {
436
471
 
437
472
  module.exports = {
438
473
  DailyTab,
439
- };
474
+ };