@@ -133,7 +133,10 @@ pub struct GoalProgressView {
133133/// 新建目标(访谈确认后一步创建——status=active,无 draft 仪式)。
134134#[ tauri:: command]
135135pub fn create_goal ( state : State < ' _ , AppState > , input : GoalCreateInput ) -> Result < Goal , String > {
136- create_goal_inner ( & state. db , & input)
136+ let goal = create_goal_inner ( & state. db , & input) ?;
137+ // REQ-278:目标创建 → 广播 goals 域
138+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
139+ Ok ( goal)
137140}
138141
139142/// 全部目标卡(列表;每卡现算进度——聚合皆毫秒级查询)。
@@ -163,7 +166,12 @@ pub fn update_goal(
163166 domain_tag : Option < String > ,
164167 horizon : Option < String > ,
165168) -> Result < bool , String > {
166- update_goal_inner ( & state. db , id, & name, domain_tag, horizon)
169+ let ok = update_goal_inner ( & state. db , id, & name, domain_tag, horizon) ?;
170+ // REQ-278:目标编辑 → 广播 goals 域
171+ if ok {
172+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
173+ }
174+ Ok ( ok)
167175}
168176
169177/// 重新访谈(答案可回溯编辑——配方重推:判据/意图整体重写)。
@@ -173,19 +181,34 @@ pub fn update_goal_interview(
173181 id : i64 ,
174182 input : GoalCreateInput ,
175183) -> Result < bool , String > {
176- update_goal_interview_inner ( & state. db , id, & input)
184+ let ok = update_goal_interview_inner ( & state. db , id, & input) ?;
185+ // REQ-278:重访谈落库 → 广播 goals 域
186+ if ok {
187+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
188+ }
189+ Ok ( ok)
177190}
178191
179192/// 删除目标(里程碑/绑定 CASCADE;M1 无快照——毕业快照保留属 M2)。
180193#[ tauri:: command]
181194pub fn delete_goal ( state : State < ' _ , AppState > , id : i64 ) -> Result < bool , String > {
182- delete_goal_inner ( & state. db , id)
195+ let ok = delete_goal_inner ( & state. db , id) ?;
196+ // REQ-278:目标删除 → 广播 goals 域
197+ if ok {
198+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
199+ }
200+ Ok ( ok)
183201}
184202
185203/// 暂停/恢复(M1 只开放 active⇄paused;放弃/毕业随 M2 流程开放)。
186204#[ tauri:: command]
187205pub fn update_goal_status ( state : State < ' _ , AppState > , id : i64 , status : String ) -> Result < bool , String > {
188- update_goal_status_inner ( & state. db , id, & status)
206+ let ok = update_goal_status_inner ( & state. db , id, & status) ?;
207+ // REQ-278:状态流转(暂停/恢复)→ 广播 goals 域
208+ if ok {
209+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
210+ }
211+ Ok ( ok)
189212}
190213
191214/// 里程碑草案建议(宣言页预填;前端薄——单一事实源在 goal_interview.rs)。
@@ -208,7 +231,10 @@ pub fn add_goal_milestone(
208231 criteria_type : Option < String > ,
209232 ref_group_id : Option < i64 > ,
210233) -> Result < GoalMilestone , String > {
211- add_goal_milestone_inner ( & state. db , goal_id, & title, due_at, criteria_type, ref_group_id)
234+ let m = add_goal_milestone_inner ( & state. db , goal_id, & title, due_at, criteria_type, ref_group_id) ?;
235+ // REQ-278:里程碑新增 → 广播 goals 域
236+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
237+ Ok ( m)
212238}
213239
214240#[ tauri:: command]
@@ -222,31 +248,56 @@ pub fn update_goal_milestone(
222248 return Err ( "无效的里程碑 id" . to_string ( ) ) ;
223249 }
224250 let title = normalize_title ( title, "未命名里程碑" ) ;
225- state. db . update_milestone ( id, & title, due_at) . map_err ( |e| e. to_string ( ) )
251+ let ok = state. db . update_milestone ( id, & title, due_at) . map_err ( |e| e. to_string ( ) ) ?;
252+ // REQ-278:里程碑更新 → 广播 goals 域
253+ if ok {
254+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
255+ }
256+ Ok ( ok)
226257}
227258
228259#[ tauri:: command]
229260pub fn delete_goal_milestone ( state : State < ' _ , AppState > , id : i64 ) -> Result < bool , String > {
230261 if id <= 0 {
231262 return Err ( "无效的里程碑 id" . to_string ( ) ) ;
232263 }
233- state. db . delete_milestone ( id) . map_err ( |e| e. to_string ( ) )
264+ let ok = state. db . delete_milestone ( id) . map_err ( |e| e. to_string ( ) ) ?;
265+ // REQ-278:里程碑删除 → 广播 goals 域
266+ if ok {
267+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
268+ }
269+ Ok ( ok)
234270}
235271
236272#[ tauri:: command]
237273pub fn set_goal_milestone_status ( state : State < ' _ , AppState > , id : i64 , status : String ) -> Result < bool , String > {
238- set_goal_milestone_status_inner ( & state. db , id, & status)
274+ let ok = set_goal_milestone_status_inner ( & state. db , id, & status) ?;
275+ // REQ-278:里程碑状态流转 → 广播 goals 域
276+ if ok {
277+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
278+ }
279+ Ok ( ok)
239280}
240281
241282/// 绑定/解绑组(N:M——一组可服务多目标;组仍是唯一容器)。
242283#[ tauri:: command]
243284pub fn bind_goal_group ( state : State < ' _ , AppState > , goal_id : i64 , group_id : i64 ) -> Result < bool , String > {
244- bind_goal_group_inner ( & state. db , goal_id, group_id)
285+ let ok = bind_goal_group_inner ( & state. db , goal_id, group_id) ?;
286+ // REQ-278:绑组(N:M)→ 广播 goals 域(组侧服务标随目标页刷新)
287+ if ok {
288+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
289+ }
290+ Ok ( ok)
245291}
246292
247293#[ tauri:: command]
248294pub fn unbind_goal_group ( state : State < ' _ , AppState > , goal_id : i64 , group_id : i64 ) -> Result < bool , String > {
249- unbind_goal_group_inner ( & state. db , goal_id, group_id)
295+ let ok = unbind_goal_group_inner ( & state. db , goal_id, group_id) ?;
296+ // REQ-278:解绑组 → 广播 goals 域
297+ if ok {
298+ crate :: notify:: emit_changed ( & state. app , crate :: notify:: DataDomain :: Goals ) ;
299+ }
300+ Ok ( ok)
250301}
251302
252303// ─────────────────────────── inner(供测试与复用) ───────────────────────────
0 commit comments