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
fe614843
Commit
fe614843
authored
May 23, 2026
by
黄同智
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'main' of
http://git.ruanyiit.com/yaoke/yaoai-video
parents
bc0bcd4b
2cdd280b
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
241 additions
and
11 deletions
+241
-11
Layout.tsx
doc/html/src/app/components/Layout.tsx
+0
-0
Dashboard.tsx
doc/html/src/app/pages/Dashboard.tsx
+0
-0
LoginPage.tsx
doc/html/src/app/pages/LoginPage.tsx
+22
-6
NewProject.tsx
doc/html/src/app/pages/NewProject.tsx
+0
-0
OutlineGeneration.tsx
doc/html/src/app/pages/OutlineGeneration.tsx
+165
-4
useAi.ts
doc/html/src/hooks/useAi.ts
+9
-1
ai.ts
doc/html/src/lib/api/ai.ts
+4
-0
theme.css
doc/html/src/styles/theme.css
+9
-0
OutlineController.java
...main/java/com/yaoai/api/controller/OutlineController.java
+9
-0
OutlinePipelineService.java
...va/com/yaoai/pipeline/service/OutlinePipelineService.java
+5
-0
OutlinePipelineServiceImpl.java
...oai/pipeline/service/impl/OutlinePipelineServiceImpl.java
+18
-0
No files found.
doc/html/src/app/components/Layout.tsx
View file @
fe614843
This diff is collapsed.
Click to expand it.
doc/html/src/app/pages/Dashboard.tsx
View file @
fe614843
This diff is collapsed.
Click to expand it.
doc/html/src/app/pages/LoginPage.tsx
View file @
fe614843
...
...
@@ -9,10 +9,20 @@ import { useAuth } from "../../hooks/useAuth";
export
function
LoginPage
()
{
const
{
login
,
loginPending
,
loginError
}
=
useAuth
();
const
[
form
,
setForm
]
=
useState
({
email
:
""
,
password
:
""
});
const
[
formError
,
setFormError
]
=
useState
<
string
|
null
>
(
null
);
const
handleSubmit
=
(
e
:
React
.
FormEvent
)
=>
{
e
.
preventDefault
();
login
(
form
);
const
email
=
form
.
email
.
trim
();
const
password
=
form
.
password
.
trim
();
if
(
!
email
||
!
password
)
{
setFormError
(
"请输入邮箱和密码"
);
return
;
}
setFormError
(
null
);
login
({
email
,
password
});
};
return
(
...
...
@@ -23,7 +33,7 @@ export function LoginPage() {
<
CardDescription
>
登录您的账号
</
CardDescription
>
</
CardHeader
>
<
CardContent
>
<
form
onSubmit=
{
handleSubmit
}
className=
"space-y-4"
>
<
form
onSubmit=
{
handleSubmit
}
className=
"space-y-4"
noValidate
>
<
div
className=
"space-y-2"
>
<
Label
htmlFor=
"email"
>
邮箱
</
Label
>
<
Input
...
...
@@ -32,7 +42,10 @@ export function LoginPage() {
placeholder=
"you@example.com"
required
value=
{
form
.
email
}
onChange=
{
(
e
)
=>
setForm
((
f
)
=>
({
...
f
,
email
:
e
.
target
.
value
}))
}
onChange=
{
(
e
)
=>
{
setFormError
(
null
);
setForm
((
f
)
=>
({
...
f
,
email
:
e
.
target
.
value
}));
}
}
/>
</
div
>
<
div
className=
"space-y-2"
>
...
...
@@ -43,13 +56,16 @@ export function LoginPage() {
placeholder=
"••••••••"
required
value=
{
form
.
password
}
onChange=
{
(
e
)
=>
setForm
((
f
)
=>
({
...
f
,
password
:
e
.
target
.
value
}))
}
onChange=
{
(
e
)
=>
{
setFormError
(
null
);
setForm
((
f
)
=>
({
...
f
,
password
:
e
.
target
.
value
}));
}
}
/>
</
div
>
{
loginError
&&
(
{
(
formError
||
loginError
)
&&
(
<
p
className=
"text-sm text-destructive"
>
{
loginError
instanceof
Error
?
loginError
.
message
:
"登录失败"
}
{
formError
??
(
loginError
instanceof
Error
?
loginError
.
message
:
"登录失败"
)
}
</
p
>
)
}
...
...
doc/html/src/app/pages/NewProject.tsx
View file @
fe614843
This diff is collapsed.
Click to expand it.
doc/html/src/app/pages/OutlineGeneration.tsx
View file @
fe614843
This diff is collapsed.
Click to expand it.
doc/html/src/hooks/useAi.ts
View file @
fe614843
import
{
useMutation
,
useQuery
,
useQueryClient
}
from
"@tanstack/react-query"
;
import
{
aiApi
}
from
"../lib/api/ai"
;
import
type
{
Character
,
Episode
,
Scene
,
Storyboard
,
StructuredVideoRequest
}
from
"../lib/api/ai"
;
import
type
{
Character
,
Episode
,
Outline
,
Scene
,
Storyboard
,
StructuredVideoRequest
}
from
"../lib/api/ai"
;
// ---- Characters ----
const
charactersKey
=
(
pid
:
string
)
=>
[
"characters"
,
pid
];
...
...
@@ -84,6 +84,14 @@ export function useGenerateOutline(projectId: string) {
});
}
export
function
useUpdateOutline
(
projectId
:
string
)
{
const
qc
=
useQueryClient
();
return
useMutation
({
mutationFn
:
(
patch
:
Partial
<
Outline
>
)
=>
aiApi
.
updateOutline
(
projectId
,
patch
),
onSuccess
:
()
=>
qc
.
invalidateQueries
({
queryKey
:
outlineKey
(
projectId
)
}),
});
}
// ---- Episodes ----
export
function
useEpisodes
(
projectId
:
string
)
{
return
useQuery
({
...
...
doc/html/src/lib/api/ai.ts
View file @
fe614843
...
...
@@ -152,6 +152,10 @@ export const aiApi = {
const
r
=
await
apiClient
.
get
(
`/projects/
${
projectId
}
/outline`
);
return
r
.
data
.
data
;
},
updateOutline
:
async
(
projectId
:
string
,
patch
:
Partial
<
Outline
>
):
Promise
<
Outline
>
=>
{
const
r
=
await
apiClient
.
put
(
`/projects/
${
projectId
}
/outline`
,
patch
);
return
r
.
data
.
data
;
},
// ---- Episodes ----
generateEpisodes
:
async
(
projectId
:
string
):
Promise
<
Episode
[]
>
=>
{
...
...
doc/html/src/styles/theme.css
View file @
fe614843
...
...
@@ -137,6 +137,15 @@
font-size
:
var
(
--font-size
);
}
html
,
body
,
#root
{
width
:
100%
;
min-width
:
0
;
height
:
100%
;
margin
:
0
;
}
h1
{
font-size
:
var
(
--text-2xl
);
font-weight
:
var
(
--font-weight-medium
);
...
...
yaoai-comic-studio/yaoai-api/src/main/java/com/yaoai/api/controller/OutlineController.java
View file @
fe614843
...
...
@@ -52,6 +52,15 @@ public class OutlineController {
return
ApiResponse
.
success
(
OutlineDTO
.
from
(
outline
));
}
@Operation
(
summary
=
"编辑项目大纲"
)
@PutMapping
(
"/outline"
)
public
ApiResponse
<
OutlineDTO
>
updateOutline
(
@PathVariable
Long
projectId
,
@RequestBody
Outline
req
)
{
Long
tenantId
=
TenantContext
.
get
();
Outline
outline
=
outlinePipelineService
.
updateOutline
(
projectId
,
tenantId
,
req
);
return
ApiResponse
.
success
(
OutlineDTO
.
from
(
outline
));
}
@Operation
(
summary
=
"生成分集内容(使用最新大纲)"
)
@PostMapping
(
"/episodes/generate"
)
public
ApiResponse
<
List
<
EpisodeDTO
>>
generateEpisodes
(
@PathVariable
Long
projectId
)
{
...
...
yaoai-comic-studio/yaoai-pipeline/src/main/java/com/yaoai/pipeline/service/OutlinePipelineService.java
View file @
fe614843
...
...
@@ -19,6 +19,11 @@ public interface OutlinePipelineService {
Outline
getOutline
(
Long
projectId
,
Long
tenantId
);
/**
* 手动编辑大纲基础信息(title/genre/synopsis/episodeCount,非 null 字段才更新)。
*/
Outline
updateOutline
(
Long
projectId
,
Long
tenantId
,
Outline
req
);
List
<
Episode
>
getEpisodes
(
Long
projectId
,
Long
tenantId
);
/**
...
...
yaoai-comic-studio/yaoai-pipeline/src/main/java/com/yaoai/pipeline/service/impl/OutlinePipelineServiceImpl.java
View file @
fe614843
...
...
@@ -205,6 +205,24 @@ public class OutlinePipelineServiceImpl implements OutlinePipelineService {
}
@Override
public
Outline
updateOutline
(
Long
projectId
,
Long
tenantId
,
Outline
req
)
{
Outline
existing
=
outlineMapper
.
findLatestByProject
(
projectId
,
tenantId
);
if
(
existing
==
null
)
{
throw
new
BizException
(
ErrorCode
.
NOT_FOUND
,
"大纲不存在,请先生成或保存大纲"
);
}
if
(
req
.
getTitle
()
!=
null
)
existing
.
setTitle
(
req
.
getTitle
());
if
(
req
.
getGenre
()
!=
null
)
existing
.
setGenre
(
req
.
getGenre
());
if
(
req
.
getSynopsis
()
!=
null
)
existing
.
setSynopsis
(
req
.
getSynopsis
());
if
(
req
.
getEpisodeCount
()
!=
null
&&
req
.
getEpisodeCount
()
>
0
)
{
existing
.
setEpisodeCount
(
req
.
getEpisodeCount
());
}
existing
.
setStatus
(
"ready"
);
outlineMapper
.
updateById
(
existing
);
log
.
info
(
"Outline updated: id={}, projectId={}"
,
existing
.
getId
(),
projectId
);
return
existing
;
}
@Override
public
List
<
Episode
>
getEpisodes
(
Long
projectId
,
Long
tenantId
)
{
return
episodeMapper
.
findByProject
(
projectId
,
tenantId
);
}
...
...
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