poi-plugin-kai-planner 1.0.8 → 1.0.10
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 +8 -1
- package/package.json +1 -1
- package/src/app/components/EquipTypeIconFilter.js +62 -0
- package/src/app/components/SlotitemTypeIcon.js +1 -20
- package/src/app/tabs/daily/DailyTab.js +557 -99
- package/src/app/tabs/wishlist/WishlistTab.js +74 -21
- package/src/app/tabs/wishlist/components/WishlistTable.js +13 -10
package/README.md
CHANGED
|
@@ -34,10 +34,17 @@
|
|
|
34
34
|
- 远端静态数据更新流程:[docs/REMOTE_DATA_UPDATE.md](docs/REMOTE_DATA_UPDATE.md)
|
|
35
35
|
|
|
36
36
|
## 2026-03 UI 更新
|
|
37
|
+
|
|
37
38
|
- Daily 页面支持按装备类型筛选;类型名来自 POI 的 `$equipTypes[api_type[3]].api_name`
|
|
38
39
|
- Daily 与 Wishlist 表格中的装备名称前都会显示装备类型 icon
|
|
39
40
|
- Wishlist 主表中的优先级改为标签样式展示(P0-P5 固定颜色)
|
|
40
41
|
- Wishlist 展开明细中的“当前持有”计数会去除改修星数大于 0 的装备以及计划起点装备
|
|
41
42
|
- 页面顶部 tab、上一次数据源更新、检查更新与更新提示统一使用 `14px` 字号
|
|
42
|
-
- Daily 与 Wishlist 主表中的装备类型 icon 统一缩小到 `16x16`
|
|
43
43
|
- Daily 与 Wishlist 主表的折叠箭头统一为:未展开 `▶`、已展开 `▼`
|
|
44
|
+
|
|
45
|
+
## 装备类型 icon 兼容性说明
|
|
46
|
+
|
|
47
|
+
- 当前所有装备类型 icon 均直接使用 POI 宿主的 `SlotitemIcon` 默认渲染尺寸
|
|
48
|
+
- 插件侧不再对 `SlotitemIcon` 做 `zoom`、`transform: scale(...)` 或其它自定义缩放处理
|
|
49
|
+
- 原因是不同用户的 POI / Electron / 系统缩放环境下,非宿主默认缩放可能导致 icon 错位、放大或整页异常
|
|
50
|
+
- 若后续仍需优化观感,优先通过 icon 外层容器的间距、行高、按钮 padding 等布局参数处理,不再恢复 icon 本体缩放
|
package/package.json
CHANGED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* src/app/components/EquipTypeIconFilter.js */
|
|
2
|
+
|
|
3
|
+
const React = require("react");
|
|
4
|
+
const { SlotitemTypeIcon } = require("./SlotitemTypeIcon");
|
|
5
|
+
|
|
6
|
+
function EquipTypeIconFilter({ options, selectedKeys, onToggle, onClear }) {
|
|
7
|
+
if (!Array.isArray(options) || options.length === 0) return null;
|
|
8
|
+
|
|
9
|
+
const selectedSet = new Set((selectedKeys || []).map(String));
|
|
10
|
+
const baseButtonStyle = {
|
|
11
|
+
display: "inline-flex",
|
|
12
|
+
alignItems: "center",
|
|
13
|
+
justifyContent: "center",
|
|
14
|
+
minWidth: 44,
|
|
15
|
+
height: 44,
|
|
16
|
+
padding: 0,
|
|
17
|
+
borderRadius: 8,
|
|
18
|
+
border: "1px solid rgba(255,255,255,0.12)",
|
|
19
|
+
background: "rgba(255,255,255,0.04)",
|
|
20
|
+
color: "#e5e7eb",
|
|
21
|
+
cursor: "pointer",
|
|
22
|
+
flexShrink: 0,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return React.createElement(
|
|
26
|
+
"div",
|
|
27
|
+
{ style: { display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" } },
|
|
28
|
+
React.createElement(
|
|
29
|
+
"button",
|
|
30
|
+
{
|
|
31
|
+
type: "button",
|
|
32
|
+
onClick: onClear,
|
|
33
|
+
style: {
|
|
34
|
+
...baseButtonStyle,
|
|
35
|
+
padding: "0 10px",
|
|
36
|
+
background: selectedSet.size === 0 ? "rgba(255,255,255,0.14)" : "rgba(255,255,255,0.04)",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
"全部"
|
|
40
|
+
),
|
|
41
|
+
...options.map((option) => {
|
|
42
|
+
const key = String(option.key);
|
|
43
|
+
const active = selectedSet.has(key);
|
|
44
|
+
return React.createElement(
|
|
45
|
+
"button",
|
|
46
|
+
{
|
|
47
|
+
key,
|
|
48
|
+
type: "button",
|
|
49
|
+
onClick: () => onToggle(key),
|
|
50
|
+
"aria-label": option.name || key,
|
|
51
|
+
style: {
|
|
52
|
+
...baseButtonStyle,
|
|
53
|
+
background: active ? "rgba(255,255,255,0.14)" : "rgba(255,255,255,0.04)",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
React.createElement(SlotitemTypeIcon, { iconType: option.iconType })
|
|
57
|
+
);
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = { EquipTypeIconFilter };
|
|
@@ -9,10 +9,6 @@ try {
|
|
|
9
9
|
|
|
10
10
|
function SlotitemTypeIcon({ iconType, title, style }) {
|
|
11
11
|
if (!iconType || !SlotitemIcon) return null;
|
|
12
|
-
const baseSize = 20;
|
|
13
|
-
const width = style && Number.isFinite(style.width) ? style.width : baseSize;
|
|
14
|
-
const height = style && Number.isFinite(style.height) ? style.height : baseSize;
|
|
15
|
-
const scale = Math.min(width / baseSize, height / baseSize);
|
|
16
12
|
|
|
17
13
|
return React.createElement(
|
|
18
14
|
"span",
|
|
@@ -22,27 +18,12 @@ function SlotitemTypeIcon({ iconType, title, style }) {
|
|
|
22
18
|
display: "inline-flex",
|
|
23
19
|
alignItems: "center",
|
|
24
20
|
justifyContent: "center",
|
|
25
|
-
width,
|
|
26
|
-
height,
|
|
27
21
|
flexShrink: 0,
|
|
28
22
|
lineHeight: 0,
|
|
29
23
|
...(style || {}),
|
|
30
24
|
},
|
|
31
25
|
},
|
|
32
|
-
React.createElement(
|
|
33
|
-
"span",
|
|
34
|
-
{
|
|
35
|
-
style: {
|
|
36
|
-
display: "inline-flex",
|
|
37
|
-
alignItems: "center",
|
|
38
|
-
justifyContent: "center",
|
|
39
|
-
width: baseSize,
|
|
40
|
-
height: baseSize,
|
|
41
|
-
zoom: scale,
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
React.createElement(SlotitemIcon, { slotitemId: iconType })
|
|
45
|
-
)
|
|
26
|
+
React.createElement(SlotitemIcon, { slotitemId: iconType })
|
|
46
27
|
);
|
|
47
28
|
}
|
|
48
29
|
|
|
@@ -1,142 +1,298 @@
|
|
|
1
1
|
/* src/app/tabs/daily/DailyTab.js */
|
|
2
2
|
|
|
3
3
|
const React = require("react");
|
|
4
|
+
|
|
4
5
|
const { SlotitemTypeIcon } = require("../../components/SlotitemTypeIcon");
|
|
5
6
|
|
|
7
|
+
const { EquipTypeIconFilter } = require("../../components/EquipTypeIconFilter");
|
|
8
|
+
|
|
6
9
|
const { loadStaticData } = require("../../../data/loaders/loadStaticData");
|
|
7
|
-
|
|
8
|
-
const {
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
buildArrangementIndex,
|
|
13
|
+
} = require("../../../data/indexes/buildArrangementIndex");
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
buildDailyViewModel,
|
|
17
|
+
} = require("../../../services/daily/buildDailyViewModel");
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
getReduxStateFromEnvWindow,
|
|
21
|
+
} = require("../../../services/player/getReduxStateFromEnvWindow");
|
|
22
|
+
|
|
10
23
|
const {
|
|
11
24
|
TOKYO_WEEK_KEYS,
|
|
25
|
+
|
|
12
26
|
TOKYO_WEEK_LABEL_ZH,
|
|
27
|
+
|
|
13
28
|
formatTokyoDateTimeWithWeekday,
|
|
29
|
+
|
|
14
30
|
getTokyoWeekdayKey,
|
|
15
31
|
} = require("../../../services/utils/tokyoTime");
|
|
16
32
|
|
|
17
33
|
function buildShipIndexes(masterShipsRaw) {
|
|
18
34
|
const shipBySortno = {};
|
|
35
|
+
|
|
19
36
|
const shipByApiId = {};
|
|
37
|
+
|
|
20
38
|
for (const k of Object.keys(masterShipsRaw || {})) {
|
|
21
39
|
const s = masterShipsRaw[k];
|
|
40
|
+
|
|
22
41
|
if (!s) continue;
|
|
42
|
+
|
|
23
43
|
if (s.api_sortno != null) shipBySortno[String(s.api_sortno)] = s;
|
|
44
|
+
|
|
24
45
|
if (s.api_id != null) shipByApiId[String(s.api_id)] = s;
|
|
25
46
|
}
|
|
47
|
+
|
|
26
48
|
return { shipBySortno, shipByApiId };
|
|
27
49
|
}
|
|
28
50
|
|
|
29
51
|
function SectionTitle({ children }) {
|
|
30
|
-
return React.createElement(
|
|
52
|
+
return React.createElement(
|
|
53
|
+
"div",
|
|
54
|
+
{ style: { fontWeight: 800, margin: "10px 0 6px" } },
|
|
55
|
+
children,
|
|
56
|
+
);
|
|
31
57
|
}
|
|
32
58
|
|
|
33
59
|
function ItemList({ title, items }) {
|
|
34
60
|
if (!items || items.length === 0) return null;
|
|
61
|
+
|
|
35
62
|
return React.createElement(
|
|
36
63
|
"div",
|
|
64
|
+
|
|
37
65
|
{ style: { marginTop: 6 } },
|
|
38
|
-
|
|
66
|
+
|
|
67
|
+
React.createElement(
|
|
68
|
+
"div",
|
|
69
|
+
{ style: { opacity: 0.85, marginBottom: 4 } },
|
|
70
|
+
title,
|
|
71
|
+
),
|
|
72
|
+
|
|
39
73
|
React.createElement(
|
|
40
74
|
"ul",
|
|
75
|
+
|
|
41
76
|
{ style: { margin: 0, paddingLeft: 18 } },
|
|
42
|
-
|
|
43
|
-
|
|
77
|
+
|
|
78
|
+
items.map((it, idx) =>
|
|
79
|
+
React.createElement("li", { key: idx }, `${it.name} × ${it.count}`),
|
|
80
|
+
),
|
|
81
|
+
),
|
|
44
82
|
);
|
|
45
83
|
}
|
|
46
84
|
|
|
47
85
|
function PhaseBlock({ phase }) {
|
|
48
86
|
const label = phase.phase === 0 ? "阶段0(0 -> 6)" : "阶段1(6 -> MAX)";
|
|
87
|
+
|
|
49
88
|
const dev = phase.dev || { min: 0, max: 0 };
|
|
89
|
+
|
|
50
90
|
const screw = phase.screw || { min: 0, max: 0 };
|
|
91
|
+
|
|
51
92
|
const extras = phase.items && phase.items.extras ? phase.items.extras : [];
|
|
52
93
|
|
|
53
94
|
return React.createElement(
|
|
54
95
|
"div",
|
|
55
|
-
|
|
96
|
+
|
|
97
|
+
{
|
|
98
|
+
style: {
|
|
99
|
+
border: "1px solid rgba(255,255,255,0.12)",
|
|
100
|
+
borderRadius: 8,
|
|
101
|
+
padding: 10,
|
|
102
|
+
marginTop: 10,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
|
|
56
106
|
React.createElement(
|
|
57
107
|
"div",
|
|
58
|
-
|
|
108
|
+
|
|
109
|
+
{
|
|
110
|
+
style: {
|
|
111
|
+
display: "flex",
|
|
112
|
+
justifyContent: "space-between",
|
|
113
|
+
gap: 12,
|
|
114
|
+
flexWrap: "wrap",
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
|
|
59
118
|
React.createElement("div", { style: { fontWeight: 800 } }, label),
|
|
60
|
-
|
|
119
|
+
|
|
120
|
+
React.createElement(
|
|
121
|
+
"div",
|
|
122
|
+
{ style: { opacity: 0.9 } },
|
|
123
|
+
`资材(开发): ${dev.min}/${dev.max},螺丝: ${screw.min}/${screw.max}`,
|
|
124
|
+
),
|
|
61
125
|
),
|
|
62
|
-
|
|
126
|
+
|
|
127
|
+
ItemList({
|
|
128
|
+
title: "通用消耗(每次)",
|
|
129
|
+
items: phase.items ? phase.items.common : [],
|
|
130
|
+
}),
|
|
131
|
+
|
|
63
132
|
extras.length > 0
|
|
64
133
|
? React.createElement(
|
|
65
134
|
"div",
|
|
135
|
+
|
|
66
136
|
{ style: { marginTop: 6 } },
|
|
67
|
-
|
|
137
|
+
|
|
138
|
+
React.createElement(
|
|
139
|
+
"div",
|
|
140
|
+
{ style: { opacity: 0.85, marginBottom: 4 } },
|
|
141
|
+
"额外消耗(特定星级区间,会叠加在通用消耗上)",
|
|
142
|
+
),
|
|
143
|
+
|
|
68
144
|
extras.map((ex, i) =>
|
|
69
145
|
React.createElement(
|
|
70
146
|
"div",
|
|
71
|
-
|
|
72
|
-
|
|
147
|
+
|
|
148
|
+
{
|
|
149
|
+
key: i,
|
|
150
|
+
style: {
|
|
151
|
+
marginTop: 6,
|
|
152
|
+
padding: "8px 10px",
|
|
153
|
+
background: "rgba(255,255,255,0.05)",
|
|
154
|
+
borderRadius: 8,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
React.createElement(
|
|
159
|
+
"div",
|
|
160
|
+
{ style: { fontWeight: 700, marginBottom: 4 } },
|
|
161
|
+
`${ex.star_from} -> ${ex.star_to}`,
|
|
162
|
+
),
|
|
163
|
+
|
|
73
164
|
React.createElement(
|
|
74
165
|
"ul",
|
|
166
|
+
|
|
75
167
|
{ style: { margin: 0, paddingLeft: 18 } },
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
168
|
+
|
|
169
|
+
(ex.items || []).map((it, idx) =>
|
|
170
|
+
React.createElement(
|
|
171
|
+
"li",
|
|
172
|
+
{ key: idx },
|
|
173
|
+
`${it.name} × ${it.count}`,
|
|
174
|
+
),
|
|
175
|
+
),
|
|
176
|
+
),
|
|
177
|
+
),
|
|
178
|
+
),
|
|
80
179
|
)
|
|
81
|
-
: null
|
|
180
|
+
: null,
|
|
82
181
|
);
|
|
83
182
|
}
|
|
84
183
|
|
|
85
184
|
function UpgradeBlock({ upgrades, upgradeMeta }) {
|
|
86
185
|
if (!upgradeMeta || upgradeMeta.hasAnyUpgradeConfig === false) {
|
|
87
|
-
return React.createElement(
|
|
186
|
+
return React.createElement(
|
|
187
|
+
"div",
|
|
188
|
+
{ style: { marginTop: 10, opacity: 0.8 } },
|
|
189
|
+
"该装备任意日期都不可进化(没有进化配置)",
|
|
190
|
+
);
|
|
88
191
|
}
|
|
89
192
|
|
|
90
193
|
if (!upgrades || upgrades.length === 0) {
|
|
91
|
-
return React.createElement(
|
|
194
|
+
return React.createElement(
|
|
195
|
+
"div",
|
|
196
|
+
{ style: { marginTop: 10, opacity: 0.8 } },
|
|
197
|
+
"该装备今天不可进化(今日可用秘书舰不符合进化要求)",
|
|
198
|
+
);
|
|
92
199
|
}
|
|
93
200
|
|
|
94
201
|
return React.createElement(
|
|
95
202
|
"div",
|
|
203
|
+
|
|
96
204
|
null,
|
|
205
|
+
|
|
97
206
|
upgrades.map((u, idx) =>
|
|
98
207
|
React.createElement(
|
|
99
208
|
"div",
|
|
100
|
-
|
|
209
|
+
|
|
210
|
+
{
|
|
211
|
+
key: idx,
|
|
212
|
+
style: {
|
|
213
|
+
border: "1px solid rgba(255,255,255,0.12)",
|
|
214
|
+
borderRadius: 8,
|
|
215
|
+
padding: 10,
|
|
216
|
+
marginTop: 10,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
React.createElement(
|
|
221
|
+
"div",
|
|
222
|
+
|
|
223
|
+
{
|
|
224
|
+
style: {
|
|
225
|
+
display: "flex",
|
|
226
|
+
justifyContent: "space-between",
|
|
227
|
+
gap: 12,
|
|
228
|
+
flexWrap: "wrap",
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
React.createElement(
|
|
233
|
+
"div",
|
|
234
|
+
{ style: { fontWeight: 900 } },
|
|
235
|
+
`进化:→ ${u.upgradeName}(${u.upgradeId})`,
|
|
236
|
+
),
|
|
237
|
+
|
|
238
|
+
React.createElement(
|
|
239
|
+
"div",
|
|
240
|
+
{ style: { opacity: 0.9 } },
|
|
241
|
+
`资材(开发): ${u.dev.min}/${u.dev.max},螺丝: ${u.screw.min}/${u.screw.max}`,
|
|
242
|
+
),
|
|
243
|
+
),
|
|
244
|
+
|
|
101
245
|
React.createElement(
|
|
102
246
|
"div",
|
|
103
|
-
{ style: {
|
|
104
|
-
|
|
105
|
-
React.createElement("div", { style: { opacity: 0.9 } }, `资材(开发): ${u.dev.min}/${u.dev.max},螺丝: ${u.screw.min}/${u.screw.max}`)
|
|
247
|
+
{ style: { marginTop: 6, opacity: 0.9 } },
|
|
248
|
+
`指定秘书舰(今日可用):${u.secretaryText || "不可"}`,
|
|
106
249
|
),
|
|
107
|
-
|
|
108
|
-
ItemList({ title: "进化消耗", items: u.items || [] })
|
|
109
|
-
)
|
|
110
|
-
)
|
|
250
|
+
|
|
251
|
+
ItemList({ title: "进化消耗", items: u.items || [] }),
|
|
252
|
+
),
|
|
253
|
+
),
|
|
111
254
|
);
|
|
112
255
|
}
|
|
113
256
|
|
|
114
257
|
function upgradeStatusText(upgradeMeta) {
|
|
115
|
-
if (!upgradeMeta || upgradeMeta.hasAnyUpgradeConfig === false)
|
|
258
|
+
if (!upgradeMeta || upgradeMeta.hasAnyUpgradeConfig === false)
|
|
259
|
+
return "不可进化";
|
|
260
|
+
|
|
116
261
|
if (upgradeMeta.canUpgradeToday) return "今日可进化";
|
|
262
|
+
|
|
117
263
|
return "今日不可进化";
|
|
118
264
|
}
|
|
119
265
|
|
|
120
266
|
class DailyTab extends React.Component {
|
|
121
267
|
constructor(props) {
|
|
122
268
|
super(props);
|
|
269
|
+
|
|
123
270
|
this.state = {
|
|
124
271
|
tokyoText: formatTokyoDateTimeWithWeekday(),
|
|
272
|
+
|
|
125
273
|
weekdayKey: getTokyoWeekdayKey(),
|
|
274
|
+
|
|
126
275
|
expanded: {},
|
|
276
|
+
|
|
127
277
|
vm: null,
|
|
278
|
+
|
|
128
279
|
error: null,
|
|
280
|
+
|
|
129
281
|
search: "",
|
|
130
|
-
|
|
282
|
+
|
|
283
|
+
selectedEquipTypes: [],
|
|
131
284
|
};
|
|
132
285
|
|
|
133
286
|
this.refresh = this.refresh.bind(this);
|
|
287
|
+
|
|
134
288
|
this.setWeekday = this.setWeekday.bind(this);
|
|
289
|
+
|
|
135
290
|
this.toggleRow = this.toggleRow.bind(this);
|
|
136
291
|
}
|
|
137
292
|
|
|
138
293
|
componentDidMount() {
|
|
139
294
|
this.refresh();
|
|
295
|
+
|
|
140
296
|
this._timer = setInterval(() => {
|
|
141
297
|
this.setState({ tokyoText: formatTokyoDateTimeWithWeekday() });
|
|
142
298
|
}, 1000);
|
|
@@ -152,34 +308,55 @@ class DailyTab extends React.Component {
|
|
|
152
308
|
|
|
153
309
|
toggleRow(equipId) {
|
|
154
310
|
const k = String(equipId);
|
|
311
|
+
|
|
155
312
|
const next = { ...(this.state.expanded || {}) };
|
|
313
|
+
|
|
156
314
|
next[k] = !next[k];
|
|
315
|
+
|
|
157
316
|
this.setState({ expanded: next });
|
|
158
317
|
}
|
|
159
318
|
|
|
160
319
|
refresh() {
|
|
161
320
|
try {
|
|
162
321
|
const staticData = loadStaticData();
|
|
163
|
-
|
|
322
|
+
|
|
323
|
+
const { index: arrangementIndex } = buildArrangementIndex(
|
|
324
|
+
staticData.improvementArrangement,
|
|
325
|
+
);
|
|
164
326
|
|
|
165
327
|
const state = getReduxStateFromEnvWindow(this.props.envWindow);
|
|
328
|
+
|
|
166
329
|
if (!state || !state.const) {
|
|
167
330
|
this.setState({
|
|
168
|
-
error:
|
|
331
|
+
error:
|
|
332
|
+
"Redux state unavailable. 请先进入母港,确保 /api_start2 已加载。",
|
|
333
|
+
|
|
169
334
|
vm: null,
|
|
170
335
|
});
|
|
336
|
+
|
|
171
337
|
return;
|
|
172
338
|
}
|
|
173
339
|
|
|
174
340
|
const masterEquipsById = state.const.$equips || {};
|
|
341
|
+
|
|
175
342
|
const masterEquipTypesById = state.const.$equipTypes || {};
|
|
343
|
+
|
|
176
344
|
const masterShipsRaw = state.const.$ships || {};
|
|
345
|
+
|
|
177
346
|
const { shipBySortno, shipByApiId } = buildShipIndexes(masterShipsRaw);
|
|
178
347
|
|
|
179
348
|
const vm = buildDailyViewModel({
|
|
180
349
|
staticData,
|
|
350
|
+
|
|
181
351
|
arrangementIndex,
|
|
182
|
-
|
|
352
|
+
|
|
353
|
+
poi: {
|
|
354
|
+
masterEquipsById,
|
|
355
|
+
masterEquipTypesById,
|
|
356
|
+
shipBySortno,
|
|
357
|
+
shipByApiId,
|
|
358
|
+
},
|
|
359
|
+
|
|
183
360
|
weekdayKey: this.state.weekdayKey,
|
|
184
361
|
});
|
|
185
362
|
|
|
@@ -192,279 +369,561 @@ class DailyTab extends React.Component {
|
|
|
192
369
|
render() {
|
|
193
370
|
const wrapperStyle = {
|
|
194
371
|
height: "calc(100vh - 140px)",
|
|
372
|
+
|
|
195
373
|
display: "flex",
|
|
374
|
+
|
|
196
375
|
flexDirection: "column",
|
|
376
|
+
|
|
197
377
|
color: "#e5e7eb",
|
|
198
|
-
|
|
378
|
+
|
|
379
|
+
fontFamily:
|
|
380
|
+
"system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial",
|
|
381
|
+
|
|
199
382
|
fontSize: 14,
|
|
383
|
+
|
|
200
384
|
lineHeight: 1.4,
|
|
201
385
|
};
|
|
202
386
|
|
|
203
387
|
const stickyHeaderStyle = {
|
|
204
388
|
position: "sticky",
|
|
389
|
+
|
|
205
390
|
top: 0,
|
|
391
|
+
|
|
206
392
|
zIndex: 5,
|
|
393
|
+
|
|
207
394
|
padding: "12px 12px 10px",
|
|
395
|
+
|
|
208
396
|
background: "rgba(16,24,40,0.92)",
|
|
397
|
+
|
|
209
398
|
backdropFilter: "blur(6px)",
|
|
399
|
+
|
|
210
400
|
borderBottom: "1px solid rgba(255,255,255,0.08)",
|
|
211
401
|
};
|
|
212
402
|
|
|
213
|
-
const headerRowStyle = {
|
|
214
|
-
|
|
403
|
+
const headerRowStyle = {
|
|
404
|
+
display: "flex",
|
|
405
|
+
justifyContent: "space-between",
|
|
406
|
+
gap: 12,
|
|
407
|
+
alignItems: "center",
|
|
408
|
+
flexWrap: "wrap",
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
const tabBarStyle = {
|
|
412
|
+
display: "flex",
|
|
413
|
+
gap: 8,
|
|
414
|
+
flexWrap: "wrap",
|
|
415
|
+
marginTop: 10,
|
|
416
|
+
};
|
|
417
|
+
|
|
215
418
|
const tabStyle = (active) => ({
|
|
216
419
|
padding: "6px 10px",
|
|
420
|
+
|
|
217
421
|
borderRadius: 10,
|
|
422
|
+
|
|
218
423
|
border: "1px solid rgba(255,255,255,0.12)",
|
|
424
|
+
|
|
219
425
|
background: active ? "rgba(255,255,255,0.12)" : "transparent",
|
|
426
|
+
|
|
220
427
|
cursor: "pointer",
|
|
428
|
+
|
|
221
429
|
userSelect: "none",
|
|
222
430
|
});
|
|
223
|
-
|
|
431
|
+
|
|
432
|
+
const toolbarStyle = {
|
|
433
|
+
display: "flex",
|
|
434
|
+
gap: 8,
|
|
435
|
+
alignItems: "center",
|
|
436
|
+
flexWrap: "wrap",
|
|
437
|
+
};
|
|
224
438
|
|
|
225
439
|
const inputStyle = {
|
|
226
440
|
width: 240,
|
|
441
|
+
|
|
227
442
|
padding: "6px 10px",
|
|
443
|
+
|
|
228
444
|
borderRadius: 8,
|
|
445
|
+
|
|
229
446
|
border: "1px solid rgba(255,255,255,0.12)",
|
|
447
|
+
|
|
230
448
|
background: "rgba(0,0,0,0.15)",
|
|
449
|
+
|
|
231
450
|
color: "#e5e7eb",
|
|
451
|
+
|
|
232
452
|
outline: "none",
|
|
453
|
+
|
|
233
454
|
fontSize: 14,
|
|
234
455
|
};
|
|
235
456
|
|
|
236
457
|
const scrollAreaStyle = {
|
|
237
458
|
flex: 1,
|
|
459
|
+
|
|
238
460
|
overflowY: "auto",
|
|
461
|
+
|
|
239
462
|
padding: 12,
|
|
240
463
|
};
|
|
241
464
|
|
|
242
465
|
const tableStyle = {
|
|
243
466
|
width: "100%",
|
|
467
|
+
|
|
244
468
|
borderCollapse: "collapse",
|
|
469
|
+
|
|
245
470
|
borderSpacing: 0,
|
|
471
|
+
|
|
246
472
|
overflow: "hidden",
|
|
473
|
+
|
|
247
474
|
border: "1px solid rgba(255,255,255,0.12)",
|
|
475
|
+
|
|
248
476
|
borderRadius: 10,
|
|
477
|
+
|
|
249
478
|
background: "rgba(0,0,0,0.06)",
|
|
250
479
|
};
|
|
251
480
|
|
|
252
|
-
const thStyle = {
|
|
253
|
-
|
|
481
|
+
const thStyle = {
|
|
482
|
+
textAlign: "left",
|
|
483
|
+
padding: "10px 10px",
|
|
484
|
+
borderBottom: "1px solid rgba(255,255,255,0.12)",
|
|
485
|
+
opacity: 0.9,
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
const tdStyle = {
|
|
489
|
+
padding: "10px 10px",
|
|
490
|
+
borderBottom: "1px solid rgba(255,255,255,0.08)",
|
|
491
|
+
verticalAlign: "top",
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
const baseCostColStyle = { width: 180, minWidth: 180, maxWidth: 180 };
|
|
495
|
+
const upgradeColStyle = { width: 140, minWidth: 140, maxWidth: 140 };
|
|
496
|
+
|
|
254
497
|
const smallMuted = { opacity: 0.75, fontSize: 11 };
|
|
255
498
|
|
|
256
499
|
const vm = this.state.vm;
|
|
257
|
-
|
|
258
|
-
const
|
|
500
|
+
|
|
501
|
+
const q = String(this.state.search || "")
|
|
502
|
+
.trim()
|
|
503
|
+
.toLowerCase();
|
|
504
|
+
|
|
505
|
+
const selectedEquipTypes = Array.isArray(this.state.selectedEquipTypes)
|
|
506
|
+
? this.state.selectedEquipTypes.map(String)
|
|
507
|
+
: [];
|
|
508
|
+
|
|
509
|
+
const selectedEquipTypeSet = new Set(selectedEquipTypes);
|
|
510
|
+
|
|
259
511
|
const allRows = vm && vm.rows ? vm.rows : [];
|
|
512
|
+
|
|
260
513
|
const equipTypeOptions = [];
|
|
514
|
+
|
|
261
515
|
const seenEquipTypes = new Set();
|
|
516
|
+
|
|
262
517
|
for (const row of allRows) {
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
seenEquipTypes.
|
|
266
|
-
|
|
518
|
+
const key = row && row.iconType != null ? String(row.iconType) : "";
|
|
519
|
+
|
|
520
|
+
if (!key || seenEquipTypes.has(key)) continue;
|
|
521
|
+
|
|
522
|
+
seenEquipTypes.add(key);
|
|
523
|
+
|
|
524
|
+
equipTypeOptions.push({
|
|
525
|
+
key,
|
|
526
|
+
|
|
527
|
+
iconType: row.iconType,
|
|
528
|
+
|
|
529
|
+
name: String(row && row.equipTypeName ? row.equipTypeName : ""),
|
|
530
|
+
});
|
|
267
531
|
}
|
|
532
|
+
|
|
268
533
|
const rows = allRows.filter((r) => {
|
|
269
|
-
|
|
270
|
-
|
|
534
|
+
const typeKey = r && r.iconType != null ? String(r.iconType) : "";
|
|
535
|
+
|
|
536
|
+
if (selectedEquipTypeSet.size && !selectedEquipTypeSet.has(typeKey))
|
|
537
|
+
return false;
|
|
538
|
+
|
|
539
|
+
if (
|
|
540
|
+
q &&
|
|
541
|
+
!String(r.equipName || "")
|
|
542
|
+
.toLowerCase()
|
|
543
|
+
.includes(q)
|
|
544
|
+
)
|
|
545
|
+
return false;
|
|
546
|
+
|
|
271
547
|
return true;
|
|
272
548
|
});
|
|
273
549
|
|
|
274
550
|
return React.createElement(
|
|
275
551
|
"div",
|
|
552
|
+
|
|
276
553
|
{ style: wrapperStyle },
|
|
554
|
+
|
|
277
555
|
React.createElement(
|
|
278
556
|
"div",
|
|
557
|
+
|
|
279
558
|
{ style: stickyHeaderStyle },
|
|
559
|
+
|
|
280
560
|
React.createElement(
|
|
281
561
|
"div",
|
|
562
|
+
|
|
282
563
|
{ style: headerRowStyle },
|
|
564
|
+
|
|
283
565
|
React.createElement(
|
|
284
566
|
"div",
|
|
567
|
+
|
|
285
568
|
null,
|
|
286
|
-
|
|
287
|
-
React.createElement(
|
|
569
|
+
|
|
570
|
+
React.createElement(
|
|
571
|
+
"div",
|
|
572
|
+
{ style: { fontSize: 18, fontWeight: 900 } },
|
|
573
|
+
"每日改修",
|
|
574
|
+
),
|
|
575
|
+
|
|
576
|
+
React.createElement(
|
|
577
|
+
"div",
|
|
578
|
+
{ style: smallMuted },
|
|
579
|
+
`当前时间(GMT+9):${this.state.tokyoText}`,
|
|
580
|
+
),
|
|
288
581
|
),
|
|
582
|
+
|
|
289
583
|
React.createElement(
|
|
290
584
|
"div",
|
|
585
|
+
|
|
291
586
|
{ style: toolbarStyle },
|
|
292
|
-
|
|
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
|
-
),
|
|
587
|
+
|
|
302
588
|
React.createElement("input", {
|
|
303
589
|
value: this.state.search,
|
|
590
|
+
|
|
304
591
|
placeholder: "搜索装备名称...",
|
|
592
|
+
|
|
305
593
|
onChange: (e) => this.setState({ search: e.target.value }),
|
|
594
|
+
|
|
306
595
|
style: inputStyle,
|
|
307
596
|
}),
|
|
308
|
-
|
|
309
|
-
|
|
597
|
+
|
|
598
|
+
React.createElement("button", { onClick: this.refresh }, "刷新"),
|
|
599
|
+
),
|
|
310
600
|
),
|
|
601
|
+
|
|
602
|
+
equipTypeOptions.length
|
|
603
|
+
? React.createElement(
|
|
604
|
+
"div",
|
|
605
|
+
|
|
606
|
+
{ style: { marginTop: 10 } },
|
|
607
|
+
|
|
608
|
+
React.createElement(EquipTypeIconFilter, {
|
|
609
|
+
options: equipTypeOptions,
|
|
610
|
+
|
|
611
|
+
selectedKeys: selectedEquipTypes,
|
|
612
|
+
|
|
613
|
+
onToggle: (key) =>
|
|
614
|
+
this.setState((prev) => {
|
|
615
|
+
const current = new Set(
|
|
616
|
+
Array.isArray(prev.selectedEquipTypes)
|
|
617
|
+
? prev.selectedEquipTypes.map(String)
|
|
618
|
+
: [],
|
|
619
|
+
);
|
|
620
|
+
|
|
621
|
+
if (current.has(key)) current.delete(key);
|
|
622
|
+
else current.add(key);
|
|
623
|
+
|
|
624
|
+
return { selectedEquipTypes: Array.from(current) };
|
|
625
|
+
}),
|
|
626
|
+
|
|
627
|
+
onClear: () => this.setState({ selectedEquipTypes: [] })
|
|
628
|
+
}),
|
|
629
|
+
)
|
|
630
|
+
: null,
|
|
631
|
+
|
|
311
632
|
React.createElement(
|
|
312
633
|
"div",
|
|
634
|
+
|
|
313
635
|
{ style: tabBarStyle },
|
|
636
|
+
|
|
314
637
|
TOKYO_WEEK_KEYS.slice(1).map((k) =>
|
|
315
638
|
React.createElement(
|
|
316
639
|
"div",
|
|
640
|
+
|
|
317
641
|
{
|
|
318
642
|
key: k,
|
|
643
|
+
|
|
319
644
|
style: tabStyle(this.state.weekdayKey === k),
|
|
645
|
+
|
|
320
646
|
onClick: () => this.setWeekday(k),
|
|
321
647
|
},
|
|
322
|
-
|
|
323
|
-
|
|
648
|
+
|
|
649
|
+
TOKYO_WEEK_LABEL_ZH[k],
|
|
650
|
+
),
|
|
324
651
|
),
|
|
652
|
+
|
|
325
653
|
React.createElement(
|
|
326
654
|
"div",
|
|
655
|
+
|
|
327
656
|
{
|
|
328
657
|
key: "sunday",
|
|
658
|
+
|
|
329
659
|
style: tabStyle(this.state.weekdayKey === "sunday"),
|
|
660
|
+
|
|
330
661
|
onClick: () => this.setWeekday("sunday"),
|
|
331
662
|
},
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
663
|
+
|
|
664
|
+
TOKYO_WEEK_LABEL_ZH.sunday,
|
|
665
|
+
),
|
|
666
|
+
),
|
|
335
667
|
),
|
|
668
|
+
|
|
336
669
|
React.createElement(
|
|
337
670
|
"div",
|
|
671
|
+
|
|
338
672
|
{ style: scrollAreaStyle },
|
|
673
|
+
|
|
339
674
|
this.state.error
|
|
340
675
|
? React.createElement(
|
|
341
676
|
"pre",
|
|
677
|
+
|
|
342
678
|
{
|
|
343
679
|
style: {
|
|
344
680
|
marginTop: 0,
|
|
681
|
+
|
|
345
682
|
padding: 12,
|
|
683
|
+
|
|
346
684
|
background: "#0b1220",
|
|
685
|
+
|
|
347
686
|
border: "1px solid rgba(255,255,255,0.12)",
|
|
687
|
+
|
|
348
688
|
borderRadius: 10,
|
|
689
|
+
|
|
349
690
|
whiteSpace: "pre-wrap",
|
|
691
|
+
|
|
350
692
|
wordBreak: "break-word",
|
|
351
693
|
},
|
|
352
694
|
},
|
|
353
|
-
|
|
695
|
+
|
|
696
|
+
this.state.error,
|
|
354
697
|
)
|
|
355
698
|
: null,
|
|
699
|
+
|
|
356
700
|
!this.state.error && vm
|
|
357
701
|
? React.createElement(
|
|
358
702
|
React.Fragment,
|
|
703
|
+
|
|
359
704
|
null,
|
|
705
|
+
|
|
360
706
|
React.createElement(
|
|
361
707
|
"div",
|
|
708
|
+
|
|
362
709
|
{ style: { margin: "0 0 10px", opacity: 0.8 } },
|
|
363
|
-
|
|
710
|
+
|
|
711
|
+
`今日可改修装备:${rows.length} 条${selectedEquipTypes.length ? `(类型筛选:${selectedEquipTypes.length})` : ""}${q ? `(搜索:${this.state.search})` : ""}`,
|
|
364
712
|
),
|
|
713
|
+
|
|
365
714
|
React.createElement(
|
|
366
715
|
"table",
|
|
716
|
+
|
|
367
717
|
{ style: tableStyle },
|
|
718
|
+
|
|
368
719
|
React.createElement(
|
|
369
720
|
"thead",
|
|
721
|
+
|
|
370
722
|
null,
|
|
723
|
+
|
|
371
724
|
React.createElement(
|
|
372
725
|
"tr",
|
|
726
|
+
|
|
373
727
|
null,
|
|
728
|
+
|
|
374
729
|
React.createElement("th", { style: thStyle }, "装备名称"),
|
|
375
|
-
|
|
376
|
-
React.createElement(
|
|
377
|
-
|
|
378
|
-
|
|
730
|
+
|
|
731
|
+
React.createElement(
|
|
732
|
+
"th",
|
|
733
|
+
{ style: { ...thStyle, ...baseCostColStyle } },
|
|
734
|
+
"基础消耗(油/弹/钢/铝)",
|
|
735
|
+
),
|
|
736
|
+
|
|
737
|
+
React.createElement(
|
|
738
|
+
"th",
|
|
739
|
+
{ style: thStyle },
|
|
740
|
+
`${TOKYO_WEEK_LABEL_ZH[this.state.weekdayKey]} - 秘书舰`,
|
|
741
|
+
),
|
|
742
|
+
|
|
743
|
+
React.createElement("th", { style: { ...thStyle, ...upgradeColStyle } }, "可进化"),
|
|
744
|
+
),
|
|
379
745
|
),
|
|
746
|
+
|
|
380
747
|
React.createElement(
|
|
381
748
|
"tbody",
|
|
749
|
+
|
|
382
750
|
null,
|
|
751
|
+
|
|
383
752
|
rows.map((r) => {
|
|
384
753
|
const exp = !!this.state.expanded[String(r.equipId)];
|
|
754
|
+
|
|
385
755
|
const base = r.baseCost || {};
|
|
386
|
-
|
|
756
|
+
|
|
757
|
+
const baseText =
|
|
758
|
+
`${base.fuel || 0}/${base.ammo || 0}/${base.steel || 0}/${base.bauxite || 0}` +
|
|
759
|
+
(base.missing ? "(缺数据)" : "");
|
|
760
|
+
|
|
387
761
|
const foldIcon = exp ? "▼" : "▶";
|
|
762
|
+
|
|
388
763
|
const onRowClick = () => this.toggleRow(r.equipId);
|
|
389
764
|
|
|
390
765
|
return React.createElement(
|
|
391
766
|
React.Fragment,
|
|
767
|
+
|
|
392
768
|
{ key: r.equipId },
|
|
769
|
+
|
|
393
770
|
React.createElement(
|
|
394
771
|
"tr",
|
|
772
|
+
|
|
395
773
|
{
|
|
396
774
|
onClick: onRowClick,
|
|
775
|
+
|
|
397
776
|
style: { cursor: "pointer" },
|
|
777
|
+
|
|
398
778
|
title: "点击展开/收起",
|
|
399
779
|
},
|
|
780
|
+
|
|
400
781
|
React.createElement(
|
|
401
782
|
"td",
|
|
783
|
+
|
|
402
784
|
{ style: tdStyle },
|
|
785
|
+
|
|
403
786
|
React.createElement(
|
|
404
787
|
"div",
|
|
405
|
-
|
|
788
|
+
|
|
789
|
+
{
|
|
790
|
+
style: {
|
|
791
|
+
display: "flex",
|
|
792
|
+
gap: 8,
|
|
793
|
+
alignItems: "center",
|
|
794
|
+
},
|
|
795
|
+
},
|
|
796
|
+
|
|
406
797
|
React.createElement(
|
|
407
798
|
"button",
|
|
799
|
+
|
|
408
800
|
{
|
|
409
801
|
onClick: (e) => {
|
|
410
802
|
e.preventDefault();
|
|
803
|
+
|
|
411
804
|
e.stopPropagation();
|
|
805
|
+
|
|
412
806
|
onRowClick();
|
|
413
807
|
},
|
|
808
|
+
|
|
414
809
|
style: {
|
|
415
810
|
width: 28,
|
|
811
|
+
|
|
416
812
|
height: 28,
|
|
813
|
+
|
|
417
814
|
borderRadius: 8,
|
|
815
|
+
|
|
418
816
|
border: "1px solid rgba(255,255,255,0.12)",
|
|
817
|
+
|
|
419
818
|
background: "rgba(255,255,255,0.06)",
|
|
819
|
+
|
|
420
820
|
color: "#e5e7eb",
|
|
821
|
+
|
|
421
822
|
cursor: "pointer",
|
|
422
823
|
},
|
|
824
|
+
|
|
423
825
|
title: "展开/收起",
|
|
424
826
|
},
|
|
425
|
-
|
|
827
|
+
|
|
828
|
+
foldIcon,
|
|
426
829
|
),
|
|
427
|
-
|
|
830
|
+
|
|
831
|
+
React.createElement(SlotitemTypeIcon, {
|
|
832
|
+
iconType: r.iconType,
|
|
833
|
+
title: r.equipTypeName,
|
|
834
|
+
}),
|
|
835
|
+
|
|
428
836
|
React.createElement(
|
|
429
837
|
"div",
|
|
838
|
+
|
|
430
839
|
null,
|
|
431
|
-
|
|
432
|
-
React.createElement(
|
|
433
|
-
|
|
434
|
-
|
|
840
|
+
|
|
841
|
+
React.createElement(
|
|
842
|
+
"div",
|
|
843
|
+
{ style: { fontWeight: 400 } },
|
|
844
|
+
r.equipName,
|
|
845
|
+
),
|
|
846
|
+
|
|
847
|
+
React.createElement(
|
|
848
|
+
"div",
|
|
849
|
+
{ style: smallMuted },
|
|
850
|
+
`equipId: ${r.equipId}`,
|
|
851
|
+
),
|
|
852
|
+
),
|
|
853
|
+
),
|
|
854
|
+
),
|
|
855
|
+
|
|
856
|
+
React.createElement("td", { style: { ...tdStyle, ...baseCostColStyle } }, baseText),
|
|
857
|
+
|
|
858
|
+
React.createElement(
|
|
859
|
+
"td",
|
|
860
|
+
{ style: tdStyle },
|
|
861
|
+
r.secretaryText || "不可",
|
|
862
|
+
),
|
|
863
|
+
|
|
864
|
+
React.createElement(
|
|
865
|
+
"td",
|
|
866
|
+
{ style: { ...tdStyle, ...upgradeColStyle } },
|
|
867
|
+
upgradeStatusText(r.upgradeMeta),
|
|
435
868
|
),
|
|
436
|
-
React.createElement("td", { style: tdStyle }, baseText),
|
|
437
|
-
React.createElement("td", { style: tdStyle }, r.secretaryText || "不可"),
|
|
438
|
-
React.createElement("td", { style: tdStyle }, upgradeStatusText(r.upgradeMeta))
|
|
439
869
|
),
|
|
870
|
+
|
|
440
871
|
exp
|
|
441
872
|
? React.createElement(
|
|
442
873
|
"tr",
|
|
874
|
+
|
|
443
875
|
{ key: `${r.equipId}_detail` },
|
|
876
|
+
|
|
444
877
|
React.createElement(
|
|
445
878
|
"td",
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
879
|
+
|
|
880
|
+
{
|
|
881
|
+
style: { ...tdStyle, paddingTop: 0 },
|
|
882
|
+
colSpan: 4,
|
|
883
|
+
},
|
|
884
|
+
|
|
885
|
+
React.createElement(
|
|
886
|
+
SectionTitle,
|
|
887
|
+
null,
|
|
888
|
+
"改修消耗明细(每次)",
|
|
889
|
+
),
|
|
890
|
+
|
|
891
|
+
React.createElement(PhaseBlock, {
|
|
892
|
+
phase: r.phases[0],
|
|
893
|
+
}),
|
|
894
|
+
|
|
895
|
+
React.createElement(PhaseBlock, {
|
|
896
|
+
phase: r.phases[1],
|
|
897
|
+
}),
|
|
898
|
+
|
|
450
899
|
r.upgradeMeta && r.upgradeMeta.hasAnyUpgradeConfig
|
|
451
900
|
? React.createElement(
|
|
452
901
|
React.Fragment,
|
|
902
|
+
|
|
453
903
|
null,
|
|
454
|
-
|
|
455
|
-
React.createElement(
|
|
904
|
+
|
|
905
|
+
React.createElement(
|
|
906
|
+
SectionTitle,
|
|
907
|
+
null,
|
|
908
|
+
"进化消耗(今日可进化)",
|
|
909
|
+
),
|
|
910
|
+
|
|
911
|
+
React.createElement(UpgradeBlock, {
|
|
912
|
+
upgrades: r.upgrades || [],
|
|
913
|
+
upgradeMeta: r.upgradeMeta,
|
|
914
|
+
}),
|
|
456
915
|
)
|
|
457
|
-
: null
|
|
458
|
-
)
|
|
916
|
+
: null,
|
|
917
|
+
),
|
|
459
918
|
)
|
|
460
|
-
: null
|
|
919
|
+
: null,
|
|
461
920
|
);
|
|
462
|
-
})
|
|
463
|
-
)
|
|
464
|
-
)
|
|
921
|
+
}),
|
|
922
|
+
),
|
|
923
|
+
),
|
|
465
924
|
)
|
|
466
|
-
: null
|
|
467
|
-
)
|
|
925
|
+
: null,
|
|
926
|
+
),
|
|
468
927
|
);
|
|
469
928
|
}
|
|
470
929
|
}
|
|
@@ -472,4 +931,3 @@ class DailyTab extends React.Component {
|
|
|
472
931
|
module.exports = {
|
|
473
932
|
DailyTab,
|
|
474
933
|
};
|
|
475
|
-
|
|
@@ -31,6 +31,7 @@ const {
|
|
|
31
31
|
upsertLastResult,
|
|
32
32
|
} = require("../../../storage/userPlans/planStore");
|
|
33
33
|
const { CreatePlanForm } = require("./CreatePlanForm");
|
|
34
|
+
const { EquipTypeIconFilter } = require("../../components/EquipTypeIconFilter");
|
|
34
35
|
const { WishlistTable } = require("./components/WishlistTable");
|
|
35
36
|
const { WishlistExpandedDetail } = require("./components/WishlistExpandedDetail");
|
|
36
37
|
const { buildWishlistViewModel } = require("../../../services/wishlist/buildWishlistViewModel");
|
|
@@ -107,6 +108,7 @@ class WishlistTab extends React.Component {
|
|
|
107
108
|
rebindInputById: {},
|
|
108
109
|
editById: {},
|
|
109
110
|
filterTargetName: "",
|
|
111
|
+
selectedTargetEquipTypes: [],
|
|
110
112
|
activePlanTab: "unfinished",
|
|
111
113
|
showCreateForm: false,
|
|
112
114
|
create: {
|
|
@@ -553,18 +555,18 @@ class WishlistTab extends React.Component {
|
|
|
553
555
|
});
|
|
554
556
|
}
|
|
555
557
|
|
|
556
|
-
renderExpandedRow(plan, planWrap) {
|
|
557
|
-
const state = this.getReduxState();
|
|
558
|
-
const masterEquipsById = ((state || {}).const || {}).$equips || {};
|
|
559
|
-
return React.createElement(WishlistExpandedDetail, {
|
|
560
|
-
plan,
|
|
561
|
-
planWrap,
|
|
562
|
-
state,
|
|
563
|
-
masterEquipsById,
|
|
564
|
-
getEquipName,
|
|
565
|
-
toInt,
|
|
566
|
-
stockStatusMark,
|
|
567
|
-
});
|
|
558
|
+
renderExpandedRow(plan, planWrap) {
|
|
559
|
+
const state = this.getReduxState();
|
|
560
|
+
const masterEquipsById = ((state || {}).const || {}).$equips || {};
|
|
561
|
+
return React.createElement(WishlistExpandedDetail, {
|
|
562
|
+
plan,
|
|
563
|
+
planWrap,
|
|
564
|
+
state,
|
|
565
|
+
masterEquipsById,
|
|
566
|
+
getEquipName,
|
|
567
|
+
toInt,
|
|
568
|
+
stockStatusMark,
|
|
569
|
+
});
|
|
568
570
|
}
|
|
569
571
|
|
|
570
572
|
render() {
|
|
@@ -621,17 +623,48 @@ class WishlistTab extends React.Component {
|
|
|
621
623
|
}
|
|
622
624
|
|
|
623
625
|
const masterEquipsById = state.const.$equips || {};
|
|
624
|
-
const vm = buildWishlistViewModel({
|
|
625
|
-
plans,
|
|
626
|
-
planResults: this.state.planResults,
|
|
627
|
-
filterTargetName: this.state.filterTargetName,
|
|
628
|
-
getEquipName,
|
|
629
|
-
getEquipSortno,
|
|
630
|
-
masterEquipsById,
|
|
631
|
-
masterEquipTypesById: state.const.$equipTypes || {},
|
|
626
|
+
const vm = buildWishlistViewModel({
|
|
627
|
+
plans,
|
|
628
|
+
planResults: this.state.planResults,
|
|
629
|
+
filterTargetName: this.state.filterTargetName,
|
|
630
|
+
getEquipName,
|
|
631
|
+
getEquipSortno,
|
|
632
|
+
masterEquipsById,
|
|
633
|
+
masterEquipTypesById: state.const.$equipTypes || {},
|
|
632
634
|
});
|
|
635
|
+
const selectedTargetEquipTypes = Array.isArray(this.state.selectedTargetEquipTypes)
|
|
636
|
+
? this.state.selectedTargetEquipTypes.map(String)
|
|
637
|
+
: [];
|
|
638
|
+
const selectedTargetEquipTypeSet = new Set(selectedTargetEquipTypes);
|
|
639
|
+
const targetEquipTypeOptions = [];
|
|
640
|
+
const seenTargetEquipTypes = new Set();
|
|
641
|
+
for (const rowVm of vm.rows || []) {
|
|
642
|
+
const key = rowVm && rowVm.targetIconType != null ? String(rowVm.targetIconType) : "";
|
|
643
|
+
if (!key || seenTargetEquipTypes.has(key)) continue;
|
|
644
|
+
seenTargetEquipTypes.add(key);
|
|
645
|
+
targetEquipTypeOptions.push({
|
|
646
|
+
key,
|
|
647
|
+
iconType: rowVm.targetIconType,
|
|
648
|
+
name: String(rowVm && rowVm.targetEquipTypeName ? rowVm.targetEquipTypeName : ""),
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
const matchesSelectedTargetType = (rowVm) => {
|
|
652
|
+
const key = rowVm && rowVm.targetIconType != null ? String(rowVm.targetIconType) : "";
|
|
653
|
+
return !selectedTargetEquipTypeSet.size || selectedTargetEquipTypeSet.has(key);
|
|
654
|
+
};
|
|
655
|
+
const filteredVm = {
|
|
656
|
+
...vm,
|
|
657
|
+
rows: (vm.rows || []).filter(matchesSelectedTargetType),
|
|
658
|
+
unfinishedRows: (vm.unfinishedRows || []).filter(matchesSelectedTargetType),
|
|
659
|
+
completedRows: (vm.completedRows || []).filter(matchesSelectedTargetType),
|
|
660
|
+
};
|
|
661
|
+
filteredVm.counts = {
|
|
662
|
+
total: filteredVm.rows.length,
|
|
663
|
+
unfinished: filteredVm.unfinishedRows.length,
|
|
664
|
+
completed: filteredVm.completedRows.length,
|
|
665
|
+
};
|
|
633
666
|
const activePlanTab = this.state.activePlanTab || "unfinished";
|
|
634
|
-
const activeRows = activePlanTab === "completed" ?
|
|
667
|
+
const activeRows = activePlanTab === "completed" ? filteredVm.completedRows : filteredVm.unfinishedRows;
|
|
635
668
|
|
|
636
669
|
return React.createElement(
|
|
637
670
|
"div",
|
|
@@ -658,6 +691,26 @@ class WishlistTab extends React.Component {
|
|
|
658
691
|
React.createElement("button", { onClick: () => this.setState({ showCreateForm: true }) }, "新增改修计划"),
|
|
659
692
|
React.createElement("button", { onClick: this.refreshPlans }, "刷新")
|
|
660
693
|
),
|
|
694
|
+
targetEquipTypeOptions.length
|
|
695
|
+
? React.createElement(
|
|
696
|
+
"div",
|
|
697
|
+
{ style: { marginTop: 10 } },
|
|
698
|
+
React.createElement(EquipTypeIconFilter, {
|
|
699
|
+
options: targetEquipTypeOptions,
|
|
700
|
+
selectedKeys: selectedTargetEquipTypes,
|
|
701
|
+
onToggle: (key) =>
|
|
702
|
+
this.setState((prev) => {
|
|
703
|
+
const current = new Set(
|
|
704
|
+
Array.isArray(prev.selectedTargetEquipTypes) ? prev.selectedTargetEquipTypes.map(String) : []
|
|
705
|
+
);
|
|
706
|
+
if (current.has(key)) current.delete(key);
|
|
707
|
+
else current.add(key);
|
|
708
|
+
return { selectedTargetEquipTypes: Array.from(current) };
|
|
709
|
+
}),
|
|
710
|
+
onClear: () => this.setState({ selectedTargetEquipTypes: [] }),
|
|
711
|
+
})
|
|
712
|
+
)
|
|
713
|
+
: null,
|
|
661
714
|
React.createElement(
|
|
662
715
|
"div",
|
|
663
716
|
{ style: planTabBar },
|
|
@@ -58,6 +58,10 @@ function WishlistTable({
|
|
|
58
58
|
}) {
|
|
59
59
|
const { row, input, th, td } = styles;
|
|
60
60
|
const smallMuted = { opacity: 0.75, fontSize: 11, marginTop: 2 };
|
|
61
|
+
const priorityColStyle = { width: 100, minWidth: 100, maxWidth: 100 };
|
|
62
|
+
const targetLevelColStyle = { width: 120, minWidth: 120, maxWidth: 120 };
|
|
63
|
+
const completedColStyle = { width: 100, minWidth: 100, maxWidth: 100 };
|
|
64
|
+
const actionColStyle = { width: 180, minWidth: 180, maxWidth: 180 };
|
|
61
65
|
|
|
62
66
|
return React.createElement(
|
|
63
67
|
"table",
|
|
@@ -70,12 +74,12 @@ function WishlistTable({
|
|
|
70
74
|
null,
|
|
71
75
|
React.createElement("th", { style: th }, "目标装备"),
|
|
72
76
|
React.createElement("th", { style: th }, "起点装备(快照)"),
|
|
73
|
-
React.createElement("th", { style: th }, "优先级"),
|
|
74
|
-
React.createElement("th", { style: th }, "目标星数"),
|
|
77
|
+
React.createElement("th", { style: { ...th, ...priorityColStyle } }, "优先级"),
|
|
78
|
+
React.createElement("th", { style: { ...th, ...targetLevelColStyle } }, "目标星数"),
|
|
75
79
|
React.createElement("th", { style: th }, "备注"),
|
|
76
|
-
React.createElement("th", { style: th }, "已完成步数"),
|
|
80
|
+
React.createElement("th", { style: { ...th, ...completedColStyle } }, "已完成步数"),
|
|
77
81
|
React.createElement("th", { style: th }, "今日可改修"),
|
|
78
|
-
React.createElement("th", { style: th }, "操作")
|
|
82
|
+
React.createElement("th", { style: { ...th, ...actionColStyle } }, "操作")
|
|
79
83
|
)
|
|
80
84
|
),
|
|
81
85
|
React.createElement(
|
|
@@ -104,7 +108,7 @@ function WishlistTable({
|
|
|
104
108
|
},
|
|
105
109
|
React.createElement(
|
|
106
110
|
"td",
|
|
107
|
-
{ style: td },
|
|
111
|
+
{ style: { ...td, ...actionColStyle } },
|
|
108
112
|
React.createElement(
|
|
109
113
|
"div",
|
|
110
114
|
{ style: { display: "flex", gap: 8, alignItems: "center" } },
|
|
@@ -132,7 +136,6 @@ function WishlistTable({
|
|
|
132
136
|
React.createElement(SlotitemTypeIcon, {
|
|
133
137
|
iconType: rowVm.targetIconType,
|
|
134
138
|
title: rowVm.targetEquipTypeName,
|
|
135
|
-
style: { width: 14, height: 14 },
|
|
136
139
|
}),
|
|
137
140
|
React.createElement(
|
|
138
141
|
"div",
|
|
@@ -145,7 +148,7 @@ function WishlistTable({
|
|
|
145
148
|
React.createElement("td", { style: td }, getPlanStartSnapshotText(p)),
|
|
146
149
|
React.createElement(
|
|
147
150
|
"td",
|
|
148
|
-
{ style: td },
|
|
151
|
+
{ style: { ...td, ...priorityColStyle } },
|
|
149
152
|
isEditing
|
|
150
153
|
? React.createElement(
|
|
151
154
|
"select",
|
|
@@ -164,7 +167,7 @@ function WishlistTable({
|
|
|
164
167
|
),
|
|
165
168
|
React.createElement(
|
|
166
169
|
"td",
|
|
167
|
-
{ style: td },
|
|
170
|
+
{ style: { ...td, ...targetLevelColStyle } },
|
|
168
171
|
isEditing
|
|
169
172
|
? React.createElement("input", {
|
|
170
173
|
type: "number",
|
|
@@ -183,11 +186,11 @@ function WishlistTable({
|
|
|
183
186
|
: p.targetLevel
|
|
184
187
|
),
|
|
185
188
|
React.createElement("td", { style: td }, p.note || ""),
|
|
186
|
-
React.createElement("td", { style: td }, `${completedCount}/${totalSteps}`),
|
|
189
|
+
React.createElement("td", { style: { ...td, ...completedColStyle } }, `${completedCount}/${totalSteps}`),
|
|
187
190
|
React.createElement("td", { style: td }, today),
|
|
188
191
|
React.createElement(
|
|
189
192
|
"td",
|
|
190
|
-
{ style: td },
|
|
193
|
+
{ style: { ...td, ...actionColStyle } },
|
|
191
194
|
React.createElement(
|
|
192
195
|
"div",
|
|
193
196
|
{ style: row },
|