Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yaoai-video
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
姚珂
yaoai-video
Commits
b29011ef
Commit
b29011ef
authored
Apr 28, 2026
by
yaoke.yk
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(storyboard): harden prompt persistence and invalidation
parent
a19ab7b9
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
123 additions
and
22 deletions
+123
-22
StoryboardPipelineServiceImplTest.java
...eline/service/impl/StoryboardPipelineServiceImplTest.java
+87
-10
StoryboardPipelineServiceImpl.java
.../pipeline/service/impl/StoryboardPipelineServiceImpl.java
+36
-12
No files found.
yaoai-comic-studio/yaoai-bootstrap/src/test/java/com/yaoai/pipeline/service/impl/StoryboardPipelineServiceImplTest.java
View file @
b29011ef
package
com
.
yaoai
.
pipeline
.
service
.
impl
;
package
com
.
yaoai
.
pipeline
.
service
.
impl
;
import
com.baomidou.mybatisplus.core.conditions.AbstractWrapper
;
import
com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.yaoai.ai.core.model.ChatRequest
;
import
com.yaoai.ai.core.model.ChatRequest
;
import
com.yaoai.ai.core.service.LlmService
;
import
com.yaoai.ai.core.service.LlmService
;
import
com.yaoai.billing.service.BillingService
;
import
com.yaoai.billing.service.BillingService
;
import
com.yaoai.common.context.UserContext
;
import
com.yaoai.common.context.UserContext
;
import
com.yaoai.common.exception.BizException
;
import
com.yaoai.domain.entity.Episode
;
import
com.yaoai.domain.entity.Episode
;
import
com.yaoai.domain.entity.Scene
;
import
com.yaoai.domain.entity.Scene
;
import
com.yaoai.domain.entity.Storyboard
;
import
com.yaoai.domain.entity.Storyboard
;
...
@@ -18,16 +21,22 @@ import org.junit.jupiter.api.Test;
...
@@ -18,16 +21,22 @@ import org.junit.jupiter.api.Test;
import
org.junit.jupiter.api.extension.ExtendWith
;
import
org.junit.jupiter.api.extension.ExtendWith
;
import
org.mockito.ArgumentCaptor
;
import
org.mockito.ArgumentCaptor
;
import
org.mockito.Mock
;
import
org.mockito.Mock
;
import
org.mockito.InOrder
;
import
org.mockito.junit.jupiter.MockitoExtension
;
import
org.mockito.junit.jupiter.MockitoExtension
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertEquals
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertEquals
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertNull
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertSame
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertSame
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
import
static
org
.
mockito
.
ArgumentMatchers
.
any
;
import
static
org
.
mockito
.
ArgumentMatchers
.
any
;
import
static
org
.
mockito
.
ArgumentMatchers
.
anyLong
;
import
static
org
.
mockito
.
ArgumentMatchers
.
anyLong
;
import
static
org
.
mockito
.
ArgumentMatchers
.
argThat
;
import
static
org
.
mockito
.
Mockito
.
doThrow
;
import
static
org
.
mockito
.
Mockito
.
inOrder
;
import
static
org
.
mockito
.
Mockito
.
never
;
import
static
org
.
mockito
.
Mockito
.
never
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
verify
;
...
@@ -78,14 +87,15 @@ class StoryboardPipelineServiceImplTest {
...
@@ -78,14 +87,15 @@ class StoryboardPipelineServiceImplTest {
episode
.
setSummary
(
"summary"
);
episode
.
setSummary
(
"summary"
);
when
(
episodeMapper
.
selectById
(
11L
)).
thenReturn
(
episode
);
when
(
episodeMapper
.
selectById
(
11L
)).
thenReturn
(
episode
);
when
(
characterMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
());
when
(
characterMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
());
when
(
sceneMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
(
scene
(
"cafe"
),
scene
(
"street"
)));
when
(
sceneMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
(
scene
(
"cafe"
,
null
),
scene
(
"street"
,
"outdoor"
)));
when
(
storyboardMapper
.
insert
(
any
(
Storyboard
.
class
))).
thenAnswer
(
invocation
->
1
);
when
(
llmService
.
chat
(
any
(
ChatRequest
.
class
))).
thenReturn
(
"""
when
(
llmService
.
chat
(
any
(
ChatRequest
.
class
))).
thenReturn
(
"""
[{
[{
"
sequence_num
": 1,
"
sequence_num
": 1,
"
scene_number
": "
001
",
"
scene_number
": "
001
",
"
short_description
": "
shot
",
"
short_description
": "
shot
",
"
detailed_description
": "
detail
",
"
detailed_description
": "
detail
",
"
characters
": "
@hero
,
@cafe
,
@friend
",
"
characters
": "
@hero
,
@
street
,
@
cafe
,
@friend
",
"
dialogues
": "",
"
dialogues
": "",
"
camera_direction
": "
push
",
"
camera_direction
": "
push
",
"
composition_guide
": "
medium
",
"
composition_guide
": "
medium
",
...
@@ -98,8 +108,14 @@ class StoryboardPipelineServiceImplTest {
...
@@ -98,8 +108,14 @@ class StoryboardPipelineServiceImplTest {
List
<
Storyboard
>
storyboards
=
service
.
generateStoryboards
(
11L
,
22L
,
33L
);
List
<
Storyboard
>
storyboards
=
service
.
generateStoryboards
(
11L
,
22L
,
33L
);
assertEquals
(
1
,
storyboards
.
size
());
assertEquals
(
1
,
storyboards
.
size
());
assertEquals
(
"@
cafe
"
,
storyboards
.
get
(
0
).
getSceneRef
());
assertEquals
(
"@
street
"
,
storyboards
.
get
(
0
).
getSceneRef
());
assertEquals
(
"@hero,@friend"
,
storyboards
.
get
(
0
).
getCharacters
());
assertEquals
(
"@hero,@friend"
,
storyboards
.
get
(
0
).
getCharacters
());
ArgumentCaptor
<
ChatRequest
>
requestCaptor
=
ArgumentCaptor
.
forClass
(
ChatRequest
.
class
);
verify
(
llmService
).
chat
(
requestCaptor
.
capture
());
String
systemMessage
=
requestCaptor
.
getValue
().
getMessages
().
get
(
0
).
getContent
();
assertTrue
(
systemMessage
.
contains
(
"- @cafe ():"
));
assertTrue
(!
systemMessage
.
contains
(
"- @cafe (outdoor):"
));
}
}
@Test
@Test
...
@@ -119,6 +135,7 @@ class StoryboardPipelineServiceImplTest {
...
@@ -119,6 +135,7 @@ class StoryboardPipelineServiceImplTest {
storyboard
.
setCompositionGuide
(
"medium"
);
storyboard
.
setCompositionGuide
(
"medium"
);
storyboard
.
setDurationSeconds
(
5
);
storyboard
.
setDurationSeconds
(
5
);
when
(
storyboardMapper
.
selectById
(
7L
)).
thenReturn
(
storyboard
);
when
(
storyboardMapper
.
selectById
(
7L
)).
thenReturn
(
storyboard
);
when
(
storyboardMapper
.
updateById
(
any
(
Storyboard
.
class
))).
thenReturn
(
1
);
when
(
episodeMapper
.
selectById
(
11L
)).
thenReturn
(
new
Episode
());
when
(
episodeMapper
.
selectById
(
11L
)).
thenReturn
(
new
Episode
());
when
(
characterMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
());
when
(
characterMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
());
when
(
sceneMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
());
when
(
sceneMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
());
...
@@ -134,6 +151,10 @@ class StoryboardPipelineServiceImplTest {
...
@@ -134,6 +151,10 @@ class StoryboardPipelineServiceImplTest {
assertEquals
(
7L
,
persisted
.
getId
());
assertEquals
(
7L
,
persisted
.
getId
());
assertEquals
(
"persisted prompt"
,
persisted
.
getVideoPrompt
());
assertEquals
(
"persisted prompt"
,
persisted
.
getVideoPrompt
());
InOrder
inOrder
=
inOrder
(
billingService
,
storyboardMapper
);
inOrder
.
verify
(
billingService
).
charge
(
any
());
inOrder
.
verify
(
storyboardMapper
).
updateById
(
any
(
Storyboard
.
class
));
ArgumentCaptor
<
ChatRequest
>
requestCaptor
=
ArgumentCaptor
.
forClass
(
ChatRequest
.
class
);
ArgumentCaptor
<
ChatRequest
>
requestCaptor
=
ArgumentCaptor
.
forClass
(
ChatRequest
.
class
);
verify
(
llmService
).
chat
(
requestCaptor
.
capture
());
verify
(
llmService
).
chat
(
requestCaptor
.
capture
());
String
userMessage
=
requestCaptor
.
getValue
().
getMessages
().
get
(
1
).
getContent
();
String
userMessage
=
requestCaptor
.
getValue
().
getMessages
().
get
(
1
).
getContent
();
...
@@ -156,9 +177,10 @@ class StoryboardPipelineServiceImplTest {
...
@@ -156,9 +177,10 @@ class StoryboardPipelineServiceImplTest {
storyboard
.
setCompositionGuide
(
"wide"
);
storyboard
.
setCompositionGuide
(
"wide"
);
storyboard
.
setDurationSeconds
(
6
);
storyboard
.
setDurationSeconds
(
6
);
when
(
storyboardMapper
.
selectById
(
8L
)).
thenReturn
(
storyboard
);
when
(
storyboardMapper
.
selectById
(
8L
)).
thenReturn
(
storyboard
);
when
(
storyboardMapper
.
updateById
(
any
(
Storyboard
.
class
))).
thenReturn
(
1
);
when
(
episodeMapper
.
selectById
(
11L
)).
thenReturn
(
new
Episode
());
when
(
episodeMapper
.
selectById
(
11L
)).
thenReturn
(
new
Episode
());
when
(
characterMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
());
when
(
characterMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
());
when
(
sceneMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
(
scene
(
"cafe"
)));
when
(
sceneMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
(
scene
(
"cafe"
,
null
)));
when
(
llmService
.
chat
(
any
(
ChatRequest
.
class
))).
thenReturn
(
"legacy prompt"
);
when
(
llmService
.
chat
(
any
(
ChatRequest
.
class
))).
thenReturn
(
"legacy prompt"
);
service
.
generatePrompt
(
8L
,
33L
);
service
.
generatePrompt
(
8L
,
33L
);
...
@@ -168,6 +190,8 @@ class StoryboardPipelineServiceImplTest {
...
@@ -168,6 +190,8 @@ class StoryboardPipelineServiceImplTest {
String
userMessage
=
requestCaptor
.
getValue
().
getMessages
().
get
(
1
).
getContent
();
String
userMessage
=
requestCaptor
.
getValue
().
getMessages
().
get
(
1
).
getContent
();
assertTrue
(
userMessage
.
contains
(
"Character refs: @hero"
));
assertTrue
(
userMessage
.
contains
(
"Character refs: @hero"
));
assertTrue
(
userMessage
.
contains
(
"Scene refs: @cafe"
));
assertTrue
(
userMessage
.
contains
(
"Scene refs: @cafe"
));
assertTrue
(
userMessage
.
contains
(
"- @cafe ():"
));
assertTrue
(!
userMessage
.
contains
(
"- @cafe (outdoor):"
));
}
}
@Test
@Test
...
@@ -180,6 +204,8 @@ class StoryboardPipelineServiceImplTest {
...
@@ -180,6 +204,8 @@ class StoryboardPipelineServiceImplTest {
Storyboard
refreshed
=
new
Storyboard
();
Storyboard
refreshed
=
new
Storyboard
();
refreshed
.
setId
(
9L
);
refreshed
.
setId
(
9L
);
refreshed
.
setTenantId
(
33L
);
refreshed
.
setTenantId
(
33L
);
when
(
storyboardMapper
.
updateById
(
any
(
Storyboard
.
class
))).
thenReturn
(
1
);
when
(
storyboardMapper
.
update
(
org
.
mockito
.
ArgumentMatchers
.
isNull
(),
any
())).
thenReturn
(
1
);
when
(
storyboardMapper
.
selectById
(
9L
)).
thenReturn
(
existing
,
refreshed
);
when
(
storyboardMapper
.
selectById
(
9L
)).
thenReturn
(
existing
,
refreshed
);
Storyboard
patch
=
new
Storyboard
();
Storyboard
patch
=
new
Storyboard
();
...
@@ -195,10 +221,16 @@ class StoryboardPipelineServiceImplTest {
...
@@ -195,10 +221,16 @@ class StoryboardPipelineServiceImplTest {
assertEquals
(
9L
,
updated
.
getId
());
assertEquals
(
9L
,
updated
.
getId
());
assertEquals
(
33L
,
updated
.
getTenantId
());
assertEquals
(
33L
,
updated
.
getTenantId
());
ArgumentCaptor
<
com
.
baomidou
.
mybatisplus
.
core
.
conditions
.
Wrapper
<
Storyboard
>>
wrapperCaptor
=
ArgumentCaptor
<
UpdateWrapper
<
Storyboard
>>
wrapperCaptor
=
ArgumentCaptor
.
forClass
(
UpdateWrapper
.
class
);
ArgumentCaptor
.
forClass
(
com
.
baomidou
.
mybatisplus
.
core
.
conditions
.
Wrapper
.
class
);
verify
(
storyboardMapper
).
update
(
org
.
mockito
.
ArgumentMatchers
.
isNull
(),
wrapperCaptor
.
capture
());
verify
(
storyboardMapper
).
update
(
org
.
mockito
.
ArgumentMatchers
.
isNull
(),
wrapperCaptor
.
capture
());
assertTrue
(
wrapperCaptor
.
getValue
().
getSqlSet
().
contains
(
"video_prompt"
));
UpdateWrapper
<
Storyboard
>
wrapper
=
wrapperCaptor
.
getValue
();
assertTrue
(
wrapper
.
getSqlSet
().
contains
(
"video_prompt"
));
assertTrue
(
wrapper
.
getSqlSegment
().
contains
(
"id"
));
assertTrue
(
wrapper
.
getSqlSegment
().
contains
(
"tenant_id"
));
Map
<
String
,
Object
>
paramPairs
=
((
AbstractWrapper
<
Storyboard
,
?,
?>)
wrapper
).
getParamNameValuePairs
();
assertTrue
(
paramPairs
.
containsValue
(
9L
));
assertTrue
(
paramPairs
.
containsValue
(
33L
));
}
}
@Test
@Test
...
@@ -207,6 +239,7 @@ class StoryboardPipelineServiceImplTest {
...
@@ -207,6 +239,7 @@ class StoryboardPipelineServiceImplTest {
existing
.
setId
(
9L
);
existing
.
setId
(
9L
);
existing
.
setTenantId
(
33L
);
existing
.
setTenantId
(
33L
);
existing
.
setShortDescription
(
"same"
);
existing
.
setShortDescription
(
"same"
);
when
(
storyboardMapper
.
updateById
(
any
(
Storyboard
.
class
))).
thenReturn
(
1
);
when
(
storyboardMapper
.
selectById
(
9L
)).
thenReturn
(
existing
,
existing
);
when
(
storyboardMapper
.
selectById
(
9L
)).
thenReturn
(
existing
,
existing
);
Storyboard
patch
=
new
Storyboard
();
Storyboard
patch
=
new
Storyboard
();
...
@@ -220,6 +253,45 @@ class StoryboardPipelineServiceImplTest {
...
@@ -220,6 +253,45 @@ class StoryboardPipelineServiceImplTest {
}
}
@Test
@Test
void
update_shouldBeTransactionalAndFailWhenPromptInvalidationFails
()
throws
Exception
{
Storyboard
existing
=
new
Storyboard
();
existing
.
setId
(
9L
);
existing
.
setTenantId
(
33L
);
existing
.
setShortDescription
(
"old"
);
when
(
storyboardMapper
.
selectById
(
9L
)).
thenReturn
(
existing
);
when
(
storyboardMapper
.
updateById
(
any
(
Storyboard
.
class
))).
thenReturn
(
1
);
when
(
storyboardMapper
.
update
(
org
.
mockito
.
ArgumentMatchers
.
isNull
(),
any
())).
thenReturn
(
0
);
Storyboard
patch
=
new
Storyboard
();
patch
.
setShortDescription
(
"new"
);
assertThrows
(
BizException
.
class
,
()
->
service
.
update
(
9L
,
33L
,
patch
));
assertTrue
(
StoryboardPipelineServiceImpl
.
class
.
getMethod
(
"update"
,
Long
.
class
,
Long
.
class
,
Storyboard
.
class
)
.
isAnnotationPresent
(
Transactional
.
class
));
}
@Test
void
generatePrompt_shouldNotPersistVideoPromptWhenChargeFails
()
throws
Exception
{
Storyboard
storyboard
=
promptStoryboard
(
7L
,
11L
,
22L
,
33L
);
storyboard
.
setSceneRef
(
"@cafe"
);
when
(
storyboardMapper
.
selectById
(
7L
)).
thenReturn
(
storyboard
);
when
(
episodeMapper
.
selectById
(
11L
)).
thenReturn
(
new
Episode
());
when
(
characterMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
());
when
(
sceneMapper
.
findByProject
(
22L
,
33L
)).
thenReturn
(
List
.
of
());
when
(
llmService
.
chat
(
any
(
ChatRequest
.
class
))).
thenReturn
(
"persisted prompt"
);
doThrow
(
new
BizException
(
"TEST"
,
"charge failed"
)).
when
(
billingService
).
charge
(
any
());
assertThrows
(
BizException
.
class
,
()
->
service
.
generatePrompt
(
7L
,
33L
));
verify
(
storyboardMapper
,
never
()).
updateById
(
org
.
mockito
.
ArgumentMatchers
.<
Storyboard
>
argThat
(
storyboardArg
->
"persisted prompt"
.
equals
(
storyboardArg
.
getVideoPrompt
())
));
assertTrue
(
StoryboardPipelineServiceImpl
.
class
.
getMethod
(
"generatePrompt"
,
Long
.
class
,
Long
.
class
)
.
isAnnotationPresent
(
Transactional
.
class
));
}
@Test
void
populateMissingVideoPromptsByEpisode_shouldFillOnlyMissingRows
()
{
void
populateMissingVideoPromptsByEpisode_shouldFillOnlyMissingRows
()
{
Storyboard
missingA
=
new
Storyboard
();
Storyboard
missingA
=
new
Storyboard
();
missingA
.
setId
(
1L
);
missingA
.
setId
(
1L
);
...
@@ -227,6 +299,7 @@ class StoryboardPipelineServiceImplTest {
...
@@ -227,6 +299,7 @@ class StoryboardPipelineServiceImplTest {
missingB
.
setId
(
2L
);
missingB
.
setId
(
2L
);
Storyboard
full
=
new
Storyboard
();
Storyboard
full
=
new
Storyboard
();
full
.
setId
(
3L
);
full
.
setId
(
3L
);
when
(
storyboardMapper
.
updateById
(
any
(
Storyboard
.
class
))).
thenReturn
(
1
);
when
(
storyboardMapper
.
findMissingVideoPromptByEpisode
(
44L
,
33L
)).
thenReturn
(
List
.
of
(
missingA
,
missingB
));
when
(
storyboardMapper
.
findMissingVideoPromptByEpisode
(
44L
,
33L
)).
thenReturn
(
List
.
of
(
missingA
,
missingB
));
when
(
storyboardMapper
.
findByEpisode
(
44L
,
33L
)).
thenReturn
(
List
.
of
(
missingA
,
missingB
,
full
));
when
(
storyboardMapper
.
findByEpisode
(
44L
,
33L
)).
thenReturn
(
List
.
of
(
missingA
,
missingB
,
full
));
when
(
storyboardMapper
.
selectById
(
1L
)).
thenReturn
(
promptStoryboard
(
1L
,
44L
,
22L
,
33L
));
when
(
storyboardMapper
.
selectById
(
1L
)).
thenReturn
(
promptStoryboard
(
1L
,
44L
,
22L
,
33L
));
...
@@ -239,12 +312,16 @@ class StoryboardPipelineServiceImplTest {
...
@@ -239,12 +312,16 @@ class StoryboardPipelineServiceImplTest {
List
<
Storyboard
>
result
=
service
.
populateMissingVideoPromptsByEpisode
(
44L
,
33L
);
List
<
Storyboard
>
result
=
service
.
populateMissingVideoPromptsByEpisode
(
44L
,
33L
);
assertEquals
(
3
,
result
.
size
());
assertEquals
(
3
,
result
.
size
());
verify
(
storyboardMapper
,
times
(
2
)).
updateById
(
any
(
Storyboard
.
class
));
verify
(
storyboardMapper
,
never
()).
selectById
(
3L
);
ArgumentCaptor
<
Storyboard
>
updateCaptor
=
ArgumentCaptor
.
forClass
(
Storyboard
.
class
);
verify
(
storyboardMapper
,
times
(
2
)).
updateById
(
updateCaptor
.
capture
());
assertEquals
(
List
.
of
(
1L
,
2L
),
updateCaptor
.
getAllValues
().
stream
().
map
(
Storyboard:
:
getId
).
toList
());
}
}
private
static
Scene
scene
(
String
name
)
{
private
static
Scene
scene
(
String
name
,
String
sceneType
)
{
Scene
scene
=
new
Scene
();
Scene
scene
=
new
Scene
();
scene
.
setName
(
name
);
scene
.
setName
(
name
);
scene
.
setSceneType
(
sceneType
);
return
scene
;
return
scene
;
}
}
...
...
yaoai-comic-studio/yaoai-pipeline/src/main/java/com/yaoai/pipeline/service/impl/StoryboardPipelineServiceImpl.java
View file @
b29011ef
...
@@ -23,6 +23,7 @@ import com.yaoai.pipeline.service.StoryboardPipelineService;
...
@@ -23,6 +23,7 @@ import com.yaoai.pipeline.service.StoryboardPipelineService;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
...
@@ -193,6 +194,7 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
...
@@ -193,6 +194,7 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
}
}
@Override
@Override
@Transactional
public
Storyboard
update
(
Long
id
,
Long
tenantId
,
Storyboard
patch
)
{
public
Storyboard
update
(
Long
id
,
Long
tenantId
,
Storyboard
patch
)
{
Storyboard
existing
=
storyboardMapper
.
selectById
(
id
);
Storyboard
existing
=
storyboardMapper
.
selectById
(
id
);
if
(
existing
==
null
||
!
tenantId
.
equals
(
existing
.
getTenantId
()))
{
if
(
existing
==
null
||
!
tenantId
.
equals
(
existing
.
getTenantId
()))
{
...
@@ -202,7 +204,10 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
...
@@ -202,7 +204,10 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
boolean
bodyFieldsChanged
=
hasStoryboardBodyChanges
(
existing
,
patch
);
boolean
bodyFieldsChanged
=
hasStoryboardBodyChanges
(
existing
,
patch
);
patch
.
setId
(
id
);
patch
.
setId
(
id
);
patch
.
setTenantId
(
tenantId
);
patch
.
setTenantId
(
tenantId
);
storyboardMapper
.
updateById
(
patch
);
int
updatedRows
=
storyboardMapper
.
updateById
(
patch
);
if
(
updatedRows
!=
1
)
{
throw
new
BizException
(
ErrorCode
.
INTERNAL_ERROR
,
"Failed to update storyboard"
);
}
if
(
bodyFieldsChanged
)
{
if
(
bodyFieldsChanged
)
{
clearVideoPrompt
(
id
,
tenantId
);
clearVideoPrompt
(
id
,
tenantId
);
}
}
...
@@ -226,6 +231,7 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
...
@@ -226,6 +231,7 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
}
}
@Override
@Override
@Transactional
public
String
generatePrompt
(
Long
storyboardId
,
Long
tenantId
)
{
public
String
generatePrompt
(
Long
storyboardId
,
Long
tenantId
)
{
Storyboard
storyboard
=
storyboardMapper
.
selectById
(
storyboardId
);
Storyboard
storyboard
=
storyboardMapper
.
selectById
(
storyboardId
);
if
(
storyboard
==
null
||
!
tenantId
.
equals
(
storyboard
.
getTenantId
()))
{
if
(
storyboard
==
null
||
!
tenantId
.
equals
(
storyboard
.
getTenantId
()))
{
...
@@ -271,7 +277,7 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
...
@@ -271,7 +277,7 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
userMsg
.
append
(
String
.
format
(
userMsg
.
append
(
String
.
format
(
"- @%s (%s): %s%n"
,
"- @%s (%s): %s%n"
,
nullSafe
(
scene
.
getName
()),
nullSafe
(
scene
.
getName
()),
"indoor"
.
equals
(
scene
.
getSceneType
())
?
"indoor"
:
"outdoor"
,
sceneTypeLabel
(
scene
.
getSceneType
())
,
nullSafe
(
scene
.
getDescription
())
nullSafe
(
scene
.
getDescription
())
));
));
}
}
...
@@ -331,11 +337,6 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
...
@@ -331,11 +337,6 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
String
prompt
=
llmService
.
chat
(
request
);
String
prompt
=
llmService
.
chat
(
request
);
Storyboard
promptUpdate
=
new
Storyboard
();
promptUpdate
.
setId
(
storyboard
.
getId
());
promptUpdate
.
setVideoPrompt
(
prompt
);
storyboardMapper
.
updateById
(
promptUpdate
);
billingService
.
charge
(
BillingChargeRequest
.
builder
()
billingService
.
charge
(
BillingChargeRequest
.
builder
()
.
tenantId
(
tenantId
)
.
tenantId
(
tenantId
)
.
userId
(
UserContext
.
require
())
.
userId
(
UserContext
.
require
())
...
@@ -348,6 +349,14 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
...
@@ -348,6 +349,14 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
.
unitCount
(
1
)
.
unitCount
(
1
)
.
refId
(
String
.
valueOf
(
storyboardId
))
.
refId
(
String
.
valueOf
(
storyboardId
))
.
build
());
.
build
());
Storyboard
promptUpdate
=
new
Storyboard
();
promptUpdate
.
setId
(
storyboard
.
getId
());
promptUpdate
.
setVideoPrompt
(
prompt
);
int
updatedRows
=
storyboardMapper
.
updateById
(
promptUpdate
);
if
(
updatedRows
!=
1
)
{
throw
new
BizException
(
ErrorCode
.
INTERNAL_ERROR
,
"Failed to persist storyboard prompt"
);
}
return
prompt
;
return
prompt
;
}
}
...
@@ -388,7 +397,7 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
...
@@ -388,7 +397,7 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
context
.
append
(
String
.
format
(
context
.
append
(
String
.
format
(
"- @%s (%s): %s%n"
,
"- @%s (%s): %s%n"
,
nullSafe
(
scene
.
getName
()),
nullSafe
(
scene
.
getName
()),
"indoor"
.
equals
(
scene
.
getSceneType
())
?
"indoor"
:
"outdoor"
,
sceneTypeLabel
(
scene
.
getSceneType
())
,
nullSafe
(
scene
.
getDescription
())
nullSafe
(
scene
.
getDescription
())
));
));
}
}
...
@@ -412,17 +421,19 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
...
@@ -412,17 +421,19 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
private
StoryboardRefs
splitStoryboardRefs
(
String
rawRefs
,
Set
<
String
>
sceneRefs
)
{
private
StoryboardRefs
splitStoryboardRefs
(
String
rawRefs
,
Set
<
String
>
sceneRefs
)
{
List
<
String
>
refs
=
parseRefs
(
rawRefs
);
List
<
String
>
refs
=
parseRefs
(
rawRefs
);
List
<
String
>
characterRefs
=
new
ArrayList
<>();
List
<
String
>
characterRefs
=
new
ArrayList
<>();
List
<
String
>
matchedSceneRefs
=
new
ArrayList
<>()
;
String
sceneRef
=
null
;
for
(
String
ref
:
refs
)
{
for
(
String
ref
:
refs
)
{
if
(
sceneRefs
.
contains
(
ref
))
{
if
(
sceneRefs
.
contains
(
ref
))
{
matchedSceneRefs
.
add
(
ref
);
if
(
sceneRef
==
null
)
{
sceneRef
=
ref
;
}
}
else
{
}
else
{
characterRefs
.
add
(
ref
);
characterRefs
.
add
(
ref
);
}
}
}
}
return
new
StoryboardRefs
(
joinRefs
(
characterRefs
),
joinRefs
(
matchedSceneRefs
)
);
return
new
StoryboardRefs
(
joinRefs
(
characterRefs
),
sceneRef
);
}
}
private
StoryboardRefs
promptRefsForCurrentShot
(
Storyboard
storyboard
,
List
<
Scene
>
projectScenes
)
{
private
StoryboardRefs
promptRefsForCurrentShot
(
Storyboard
storyboard
,
List
<
Scene
>
projectScenes
)
{
...
@@ -459,13 +470,16 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
...
@@ -459,13 +470,16 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
}
}
private
void
clearVideoPrompt
(
Long
storyboardId
,
Long
tenantId
)
{
private
void
clearVideoPrompt
(
Long
storyboardId
,
Long
tenantId
)
{
storyboardMapper
.
update
(
int
updatedRows
=
storyboardMapper
.
update
(
null
,
null
,
new
UpdateWrapper
<
Storyboard
>()
new
UpdateWrapper
<
Storyboard
>()
.
eq
(
"id"
,
storyboardId
)
.
eq
(
"id"
,
storyboardId
)
.
eq
(
"tenant_id"
,
tenantId
)
.
eq
(
"tenant_id"
,
tenantId
)
.
set
(
"video_prompt"
,
null
)
.
set
(
"video_prompt"
,
null
)
);
);
if
(
updatedRows
!=
1
)
{
throw
new
BizException
(
ErrorCode
.
INTERNAL_ERROR
,
"Failed to clear storyboard prompt"
);
}
}
}
private
boolean
hasStoryboardBodyChanges
(
Storyboard
existing
,
Storyboard
patch
)
{
private
boolean
hasStoryboardBodyChanges
(
Storyboard
existing
,
Storyboard
patch
)
{
...
@@ -508,6 +522,16 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
...
@@ -508,6 +522,16 @@ public class StoryboardPipelineServiceImpl implements StoryboardPipelineService
return
value
!=
null
?
value
:
""
;
return
value
!=
null
?
value
:
""
;
}
}
private
String
sceneTypeLabel
(
String
sceneType
)
{
if
(
"indoor"
.
equals
(
sceneType
))
{
return
"indoor"
;
}
if
(
"outdoor"
.
equals
(
sceneType
))
{
return
"outdoor"
;
}
return
""
;
}
private
record
StoryboardRefs
(
String
characters
,
String
sceneRef
)
{
private
record
StoryboardRefs
(
String
characters
,
String
sceneRef
)
{
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment