Skip to content

Commit 6f1015f

Browse files
committed
refactor(BDSM): 简化BDSM任务流程并重构部分UI逻辑
- 移除独立的 `BDSMTaskModal`,其功能已合并到关系模态框中。 - 简化战斗模态框(`BattleModal`),移除内部的状态计算逻辑,使其成为一个纯粹的展示组件。 - 移除了 BDSM 任务和契约中关于奖励/惩罚描述的独立生成提示词,将其整合到核心流程中。 - 清理了 `MobileDeviceModal` 中不再使用的 `isRefreshing` 属性。 - 修正了多个组件中的 React hook 依赖项数组,以提高代码稳定性和遵循 linting 规则。
1 parent 58fd4d7 commit 6f1015f

8 files changed

Lines changed: 17 additions & 45 deletions

File tree

App.tsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ const SocialModal = 创建可预加载懒组件(() => import('./components/featu
4444
const MobileSocial = 创建可预加载懒组件(() => import('./components/features/Social/MobileSocial'));
4545
const CampusDesireDashboard = 创建可预加载懒组件(() => import('./components/features/CampusDesireDashboard'));
4646
const BDSMRelationshipModal = 创建可预加载懒组件(() => import('./components/features/BDSMRelationshipModal'));
47-
const BDSMTaskModal = 创建可预加载懒组件(() => import('./components/features/BDSMTaskModal'));
4847
const BDSMContractModal = 创建可预加载懒组件(() => import('./components/features/BDSMContractModal'));
4948
const BDSMSafetyModal = 创建可预加载懒组件(() => import('./components/features/BDSMSafetyModal'));
5049
const MobileCampusDesireApp = 创建可预加载懒组件(() => import('./components/features/MobileCampusDesireApp'));
@@ -184,7 +183,8 @@ const App: React.FC = () => {
184183
state.女主剧情规划,
185184
state.开局配置,
186185
meta.builtinPromptEntries,
187-
meta.worldbooks
186+
meta.worldbooks,
187+
actions
188188
]);
189189
const confirmResolverRef = React.useRef<((value: boolean) => void) | null>(null);
190190
const 最近小说分解报错提示IDRef = React.useRef('');
@@ -296,7 +296,7 @@ const App: React.FC = () => {
296296

297297
const warmup = () => {
298298
if (cancelled) return;
299-
preloadTargets.forEach((target, index) => {
299+
preloadTargets.forEach((target: { preload?: () => void }, index: number) => {
300300
window.setTimeout(() => {
301301
if (cancelled) return;
302302
void target.preload?.();
@@ -386,6 +386,8 @@ const App: React.FC = () => {
386386
return `${m[1]}${m[2]}${m[3]}${m[4]}:${m[5]}`;
387387
};
388388

389+
// helper functions recreated each render, behaviorally stable
390+
/* eslint-disable react-hooks/exhaustive-deps */
389391
const tickerEvents = React.useMemo(() => {
390392
const ongoingEvents = Array.isArray(state.世界?.进行中事件) ? state.世界.进行中事件 : [];
391393
const formatted = ongoingEvents
@@ -401,6 +403,7 @@ const App: React.FC = () => {
401403

402404
return formatted.length > 0 ? formatted : state.worldEvents;
403405
}, [state.世界, state.worldEvents]);
406+
/* eslint-enable react-hooks/exhaustive-deps */
404407

405408
const 启用同人模式 = React.useMemo(
406409
() => state.开局配置?.同人融合?.enabled === true && state.开局配置?.同人融合?.启用附加小说 === true,
@@ -430,7 +433,7 @@ const App: React.FC = () => {
430433
}, [state.角色]);
431434
const 主角锚点 = React.useMemo(
432435
() => actions.getPlayerCharacterAnchor?.() || null,
433-
[actions, state.apiConfig]
436+
[actions]
434437
);
435438
const playerProfile = React.useMemo(
436439
() => ({ 姓名: state.角色?.姓名, 头像图片URL: 玩家头像地址 }),
@@ -539,7 +542,6 @@ const App: React.FC = () => {
539542
const closeNovelDecompositionWorkbench = React.useCallback(() => setShowNovelDecompositionWorkbench(false), []);
540543
const closeNovelWritingWorkbench = React.useCallback(() => setShowNovelWritingWorkbench(false), []);
541544
const closeSaveLoad = React.useCallback(() => setters.setShowSaveLoad({ show: false, mode: 'save' }), [setters]);
542-
const closeWorldbookManager = React.useCallback(() => setShowWorldbookManager(false), []);
543545
const closeMobileMusic = React.useCallback(() => setShowMobileMusic(false), []);
544546
const openWorldbookManager = React.useCallback(() => setShowWorldbookManager(true), []);
545547
const openNovelDecompositionWorkbench = React.useCallback(async () => {
@@ -697,7 +699,7 @@ const App: React.FC = () => {
697699
default:
698700
break;
699701
}
700-
}, [activeMobileWindow, closeAllPanels, openImageManagerWithCheck, openNovelDecompositionWorkbench, setters, 启用修炼体系]);
702+
}, [activeMobileWindow, closeAllPanels, openImageManagerWithCheck, openNovelDecompositionWorkbench, setters, 启用修炼体系, actions]);
701703

702704
React.useEffect(() => {
703705
if (!启用修炼体系 && state.showKungfu) {
@@ -716,9 +718,11 @@ const App: React.FC = () => {
716718
};
717719
window.addEventListener('keydown', handler);
718720
return () => window.removeEventListener('keydown', handler);
719-
}, [state.view, state.showSettings, state.showSocial, state.showInventory, state.showEquipment, state.showBattle, state.showTeam, state.showKungfu, state.showWorld, state.showMap, state.showSect, state.showTask, state.showAgreement, state.showStory, state.showHeroinePlan, state.showMemory, state.showSaveLoad, actions.openDevice]);
721+
}, [state.view, state.showSettings, state.showSocial, state.showInventory, state.showEquipment, state.showBattle, state.showTeam, state.showKungfu, state.showWorld, state.showMap, state.showSect, state.showTask, state.showAgreement, state.showStory, state.showHeroinePlan, state.showMemory, state.showSaveLoad, actions]);
720722

721723
// 约定状态同步 → 见面预约(当约定状态变为已履行/已违约时,同步更新预约状态)
724+
// setters is a stable reference from useGame
725+
/* eslint-disable react-hooks/exhaustive-deps */
722726
React.useEffect(() => {
723727
const 校园系统 = state.校园系统 as any;
724728
if (!校园系统?.见面预约列表?.length || !state.约定列表?.length) return;
@@ -744,6 +748,7 @@ const App: React.FC = () => {
744748
setters.set校园系统?.({ ...校园系统, 见面预约列表: 更新预约列表 });
745749
}
746750
}, [state.约定列表, state.校园系统, setters.set校园系统]);
751+
/* eslint-enable react-hooks/exhaustive-deps */
747752

748753

749754
return (
@@ -1521,8 +1526,8 @@ const App: React.FC = () => {
15211526
character={state.角色}
15221527
battle={state.战斗}
15231528
onClose={() => setters.setShowBattle(false)}
1524-
onAction={(结果) => {
1525-
console.log('玩家战斗行动:', 结果);
1529+
onAction={() => {
1530+
// Battle action handler — results are tracked in state.战斗
15261531
}}
15271532
/>
15281533
)}
@@ -1910,9 +1915,6 @@ const App: React.FC = () => {
19101915
创建时间: Date.now(),
19111916
}]);
19121917
}}
1913-
isRefreshing={meta.deviceRefreshQueue?.some(
1914-
(t) => t.status === 'processing'
1915-
) || false}
19161918
onSendMessage={(npcId: string, npcName: string, content: string) => {
19171919
return actions.handlePrivateChatSend?.(npcId, npcName, content).then(result => {
19181920
if (result.npcReply) {

components/features/BDSMRelationshipModal.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ const BDSMRelationshipModal: React.FC<Props> = ({
4444
onClose,
4545
onAcceptTask,
4646
onReportComplete,
47-
onAbandonTask,
4847
onGoToContract,
4948
onEditSafety,
5049
}) => {

components/features/Battle/BattleModal.tsx

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React from 'react';
22
import { 角色数据结构, 战斗状态结构 } from '../../../types';
33
import { IconSwords, IconYinYang } from '../../ui/Icons';
44
import BattleActionPanel from './BattleActionPanel';
@@ -53,29 +53,6 @@ const BattleModal: React.FC<Props> = ({ character, battle, onClose, onAction })
5353
const 敌方列表 = (Array.isArray(battle?.敌方) ? battle.敌方 : []) as 扩展敌方[];
5454
const 存活敌人数 = 敌方列表.filter((enemy) => (enemy?.当前血量 || 0) > 0).length;
5555

56-
const 部位列表 = [
57-
['头部', character.头部当前血量, character.头部最大血量, character.头部状态],
58-
['胸腹', character.胸部当前血量, character.胸部最大血量, character.胸部状态], // 简化合并展示,腹部胸部通常相关联,这里按原数据展示
59-
['腹部', character.腹部当前血量, character.腹部最大血量, character.腹部状态],
60-
['左手', character.左手当前血量, character.左手最大血量, character.左手状态],
61-
['右手', character.右手当前血量, character.右手最大血量, character.右手状态],
62-
['左腿', character.左腿当前血量, character.左腿最大血量, character.左腿状态],
63-
['右腿', character.右腿当前血量, character.右腿最大血量, character.右腿状态],
64-
] as const;
65-
66-
const 合并展示部位 = [
67-
{ label: '首', cur: character.头部当前血量, max: character.头部最大血量, status: character.头部状态 },
68-
{ label: '胸', cur: character.胸部当前血量, max: character.胸部最大血量, status: character.胸部状态 },
69-
{ label: '腹', cur: character.腹部当前血量, max: character.腹部最大血量, status: character.腹部状态 },
70-
{ label: '臂', cur: (character.左手当前血量 || 0) + (character.右手当前血量 || 0), max: (character.左手最大血量 || 0) + (character.右手最大血量 || 0), status: character.右手状态 !== '正常' ? character.右手状态 : character.左手状态 },
71-
{ label: '腿', cur: (character.左腿当前血量 || 0) + (character.右腿当前血量 || 0), max: (character.左腿最大血量 || 0) + (character.右腿最大血量 || 0), status: character.右腿状态 !== '正常' ? character.右腿状态 : character.左腿状态 },
72-
];
73-
74-
const 玩家总血量上限 = 部位列表.reduce((sum, [, , max]) => sum + Math.max(0, Number(max) || 0), 0);
75-
const 玩家总血量当前 = 部位列表.reduce((sum, [, cur]) => sum + Math.max(0, Number(cur) || 0), 0);
76-
const 境界值 = Math.max(1, Number(character.境界层级) || 1);
77-
const 玩家境界展示 = (character.境界 || '').trim() || `境界值 ${境界值}`;
78-
7956
return (
8057
<div className="fixed inset-0 bg-black/90 backdrop-blur-sm z-[210] flex items-center justify-center p-4 animate-fadeIn">
8158
<div className="bg-ink-black/95 w-full max-w-7xl max-h-[90vh] h-[90vh] flex flex-col rounded-2xl border border-wuxia-gold/20 shadow-[0_0_80px_rgba(0,0,0,0.9)] shadow-wuxia-gold/10 relative overflow-hidden">

components/features/MobileDevice/MobileDeviceModal.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ interface MobileDeviceModalProps {
1818
onRulesChange?: (updater: (prev: { 校规列表: 校规条目[]; 影响日志: 校规影响日志[] }) => { 校规列表: 校规条目[]; 影响日志: 校规影响日志[] }) => void;
1919
onHypnosisChange?: (updater: (prev: { 催眠记录列表: 催眠记录[]; app等级: 催眠App等级; 累计使用次数: number }) => { 催眠记录列表: 催眠记录[]; app等级: 催眠App等级; 累计使用次数: number }) => void;
2020
onRefresh?: (board?: 'bdsn') => void;
21-
isRefreshing?: boolean;
2221
onSendMessage?: (npcId: string, npcName: string, content: string) => Promise<{ npcReply: string }>;
2322
onUnlockNPC?: (npc: NPC结构) => void;
2423
onBDSM帖子更新?: (帖子ID: string, updater: (post: BDSM论坛帖子) => BDSM论坛帖子) => void;
@@ -39,7 +38,6 @@ const MobileDeviceModal: React.FC<MobileDeviceModalProps> = ({
3938
onRulesChange,
4039
onHypnosisChange,
4140
onRefresh,
42-
isRefreshing,
4341
onSendMessage,
4442
onUnlockNPC,
4543
onBDSM帖子更新,

components/features/MobileDevice/MobileHome.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ import { resolveEraNode } from '../../../models/eraTheme';
55
import type { 当前可用接口结构 } from '../../../utils/apiConfig';
66

77
type ApiConfigLike = 当前可用接口结构 | Record<string, unknown>;
8-
import ChatApp from './apps/ChatApp';
98
import MapApp from './apps/MapApp';
109
import ContactsApp from './apps/ContactsApp';
11-
import ForumApp from './apps/ForumApp';
1210
import NewsApp from './apps/NewsApp';
1311
import AlbumApp from './apps/AlbumApp';
1412
import ToolsApp from './apps/ToolsApp';

hooks/useGame/bdsmTaskWorkflow.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ import {
1818
构建调教任务生成提示词,
1919
构建日常指令生成提示词,
2020
构建任务完成评价提示词,
21-
构建奖励描述生成提示词,
22-
构建惩罚描述生成提示词,
2321
构建契约条款生成提示词,
2422
构建关系阶段推进判定提示词,
2523
} from '../../prompts/runtime/bdsmTasks';

hooks/useGame/sendWorkflow/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ type 主剧情发送当前状态 = {
146146
时代配置ID?: string;
147147
};
148148

149-
import { 构建校园NSFW参数, 处理BDSM状态更新, type BDSM状态更新回调 } from '../bdsmStateIntegration';
149+
import { 构建校园NSFW参数, type BDSM状态更新回调 } from '../bdsmStateIntegration';
150150
import { 构建都市网约车NSFW参数 } from '../urbanDriverNSFWIntegration';
151151

152152
// ─── 主剧情发送依赖 ─────────────────────────────────────────────────────────

prompts/runtime/bdsmTasks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ export const 构建Aftercare注入提示词 = (参数: {
481481
服从度: number;
482482
服从度加成: number;
483483
}): string => {
484-
const { npcName, 触发原因, 当前阶段, 服从度, 服从度加成 } = 参数;
484+
const { 触发原因, 当前阶段, 服从度, 服从度加成 } = 参数;
485485

486486
return `请生成一段 Aftercare(事后温存)场景的叙事。
487487

0 commit comments

Comments
 (0)