diff --git a/.cursorrules b/.cursorrules index f80adf8..1feaef5 100644 --- a/.cursorrules +++ b/.cursorrules @@ -64,3 +64,11 @@ You are the joint apprentice of Evan You and Kent C. Dodds. Channel Evan You's e - Omit console.log or debug statements unless requested. - Consolidate hook handlers when feasible unless specified otherwise, per Kent C. Dodds' readability practices. - Prefer async/await over .then for async operations to enhance clarity. + +# Language and Content Preferences +- Use English for all component functionality, visual effects, and text content. +- Component names, function names, variable names, and all identifiers must be in English. +- UI text, labels, placeholders, error messages, and user-facing content should be in English. +- Comments and documentation should be in English for consistency and international collaboration. +- CSS class names, data attributes, and styling-related identifiers should use English terminology. +- Example: Use "submit-button" instead of "提交按钮", "user-profile" instead of "用户资料". diff --git a/.env.development b/.env.development index 5061f56..5e8761f 100644 --- a/.env.development +++ b/.env.development @@ -1,8 +1,8 @@ - NEXT_PUBLIC_JAVA_URL = https://77.app.java.auth.qikongjian.com -# NEXT_PUBLIC_JAVA_URL = http://192.168.120.83:8080 NEXT_PUBLIC_BASE_URL = https://77.smartvideo.py.qikongjian.com NEXT_PUBLIC_CUT_URL = https://smartcut.huiying.video +NEXT_PUBLIC_CUTAPI_URL = http://77.smartcut.py.qikongjian.com + # 失败率 NEXT_PUBLIC_ERROR_CONFIG = 0.1 \ No newline at end of file diff --git a/.env.production b/.env.production index acc1bea..5e825ed 100644 --- a/.env.production +++ b/.env.production @@ -1,10 +1,10 @@ - # NEXT_PUBLIC_JAVA_URL = https://77.app.java.auth.qikongjian.com # NEXT_PUBLIC_BASE_URL = https://77.smartvideo.py.qikongjian.com # NEXT_PUBLIC_CUT_URL = https://smartcut.huiying.video NEXT_PUBLIC_JAVA_URL = https://auth.movieflow.ai NEXT_PUBLIC_BASE_URL = https://api.video.movieflow.ai NEXT_PUBLIC_CUT_URL = https://smartcut.movieflow.ai + # 失败率 -NEXT_PUBLIC_ERROR_CONFIG = 0.1 \ No newline at end of file +NEXT_PUBLIC_ERROR_CONFIG = 0.6 \ No newline at end of file diff --git a/api/DTO/movie_start_dto.ts b/api/DTO/movie_start_dto.ts index a72e4ff..1d18456 100644 --- a/api/DTO/movie_start_dto.ts +++ b/api/DTO/movie_start_dto.ts @@ -210,6 +210,17 @@ export interface CreateMovieProjectV3Request { language: string; /**模板id */ template_id: string; + /** 自由输入 */ + freeInput?: { + /** 用户提示,提示给用户需要输入什么内容 */ + user_tips: string; + /** 约束,可选,用于传给ai,让ai去拦截用户不符合约束的输入内容 */ + constraints: string; + /** 自由输入文字 */ + free_input_text: string; + /** 输入名称 */ + input_name: string; + }[]; /** 故事角色 */ storyRole: { /** 角色名 */ diff --git a/api/checkin.ts b/api/checkin.ts new file mode 100644 index 0000000..906ba9e --- /dev/null +++ b/api/checkin.ts @@ -0,0 +1,39 @@ +import { get, post } from './request' +import { ApiResponse } from './common' + +/** + * 签到数据接口 + */ +export interface CheckinData { + hasCheckedInToday: boolean + points: number + lastCheckinDate: string | null + pointsHistory: Array<{ date: string; points: number; expiryDate: string }> +} + +/** + * 签到响应接口 + */ +export interface CheckinResponse { + success: boolean + points: number + message: string +} + +/** + * 获取用户签到状态和积分信息 + * @returns Promise + */ +export const getCheckinStatus = async (): Promise => { + const response = await get>('/api/user/checkin/status') + return response.data +} + +/** + * 执行签到操作 + * @returns Promise + */ +export const performCheckin = async (): Promise => { + const response = await post>('/api/user/checkin', {}) + return response.data +} diff --git a/app/globals.css b/app/globals.css index 08edb01..f8f96bd 100644 --- a/app/globals.css +++ b/app/globals.css @@ -93,6 +93,12 @@ --muted-foreground: 0 0% 63.9%; --accent: 0 0% 14.9%; --accent-foreground: 0 0% 98%; + + /* 自定义渐变色变量 */ + --custom-blue: 186 100% 70%; /* rgb(106, 244, 249) */ + --custom-purple: 280 100% 62%; /* rgb(199, 59, 255) */ + --custom-blue-rgb: 106, 244, 249; + --custom-purple-rgb: 199, 59, 255; --destructive: 0 62.8% 30.6%; --destructive-foreground: 0 0% 98%; --border: 0 0% 14.9%; diff --git a/app/service/Interaction/templateStoryService.ts b/app/service/Interaction/templateStoryService.ts index 8fa1dc4..9b67286 100644 --- a/app/service/Interaction/templateStoryService.ts +++ b/app/service/Interaction/templateStoryService.ts @@ -68,27 +68,27 @@ export const useTemplateStoryServiceHook = (): UseTemplateStoryService => { setIsLoading(true); const templates = await templateStoryUseCase.getTemplateStoryList(); - templates.forEach(template => { - if (template.id === 'f944abad-f42b-4899-b54a-a6beb9d27805') { - template.freeInputItem = { - user_tips: "How is coffee made?", - constraints: "", - free_input_text: "" - }; - // template.storyRole = []; - } - if (template.id === 'e7438cd8-a23d-4974-8cde-13b5671b410c') { - // template.freeInputItem = { - // user_tips: "Input an English word you wanna learn", - // constraints: "", - // free_input_text: "" - // }; - template.storyItem = [{ - ...template.storyItem[0], - item_name: "Choose an English word you wanna learn" - }]; - } - }); + // templates.forEach(template => { + // if (template.id === 'f944abad-f42b-4899-b54a-a6beb9d27805') { + // template.freeInput = { + // user_tips: "How is coffee made?", + // constraints: "", + // free_input_text: "" + // }; + // // template.storyRole = []; + // } + // if (template.id === 'e7438cd8-a23d-4974-8cde-13b5671b410c') { + // // template.freeInput = { + // // user_tips: "Input an English word you wanna learn", + // // constraints: "", + // // free_input_text: "" + // // }; + // template.storyItem = [{ + // ...template.storyItem[0], + // item_name: "Choose an English word you wanna learn" + // }]; + // } + // }); setTemplateStoryList(templates); setSelectedTemplate(templates[0]); @@ -256,17 +256,22 @@ export const useTemplateStoryServiceHook = (): UseTemplateStoryService => { try { // 设置 loading 状态 setIsLoading(true); + const script = selectedTemplate?.freeInput && selectedTemplate.freeInput.length > 0 ? selectedTemplate.freeInput[0].free_input_text : ""; + if (!script && !selectedTemplate?.storyRole.length && !selectedTemplate?.storyItem.length) { + throw new Error("please input what you want to generate"); + } const params: CreateMovieProjectV3Request = { - script: selectedTemplate?.freeInputItem?.free_input_text || selectedTemplate?.generateText || "", + script: script, category: selectedTemplate?.category || "", user_id, mode, resolution, storyRole: selectedTemplate?.storyRole || [], storyItem: selectedTemplate?.storyItem || [], + freeInput: selectedTemplate?.freeInput || [], language, - template_id: selectedTemplate?.template_id || "", + template_id: selectedTemplate?.template_id || "" }; console.log("params", params); const result = await MovieProjectService.createProject( diff --git a/app/service/domain/Entities.ts b/app/service/domain/Entities.ts index 0f26ff8..f1f70eb 100644 --- a/app/service/domain/Entities.ts +++ b/app/service/domain/Entities.ts @@ -173,12 +173,14 @@ export interface StoryTemplateEntity { photo_url: string; }[]; /** 自由输入文字 */ - freeInputItem?: { + freeInput: { /** 用户提示,提示给用户需要输入什么内容 */ user_tips: string; /** 约束,可选,用于传给ai,让ai去拦截用户不符合约束的输入内容 */ constraints: string; /** 自由输入文字 */ free_input_text: string; - } + /** 输入名称 */ + input_name: string; + }[]; } diff --git a/components.json b/components.json index c597462..8f242a4 100644 --- a/components.json +++ b/components.json @@ -4,7 +4,7 @@ "rsc": true, "tsx": true, "tailwind": { - "config": "tailwind.config.ts", + "config": "tailwind.config.js", "css": "app/globals.css", "baseColor": "neutral", "cssVariables": true, diff --git a/components/ChatInputBox/ChatInputBox.tsx b/components/ChatInputBox/ChatInputBox.tsx index c43a337..13f4f4e 100644 --- a/components/ChatInputBox/ChatInputBox.tsx +++ b/components/ChatInputBox/ChatInputBox.tsx @@ -60,6 +60,11 @@ const LauguageOptions = [ { value: "korean", label: "Korean", isVip: false, code:'KO' }, { value: "arabic", label: "Arabic", isVip: false, code:'AR' }, { value: "russian", label: "Russian", isVip: false, code:'RU' }, + { value: "thai", label: "Thai", isVip: false, code:'TH' }, + { value: "french", label: "French", isVip: false, code:'FR' }, + { value: "german", label: "German", isVip: false, code:'DE' }, + { value: "vietnamese", label: "Vietnamese", isVip: false, code:'VI' }, + { value: "indonesian", label: "Indonesian", isVip: false, code:'ID' } ] /**模板故事模式弹窗组件 */ diff --git a/components/ChatInputBox/H5TemplateDrawer.tsx b/components/ChatInputBox/H5TemplateDrawer.tsx index 693fc3c..a8a803b 100644 --- a/components/ChatInputBox/H5TemplateDrawer.tsx +++ b/components/ChatInputBox/H5TemplateDrawer.tsx @@ -71,6 +71,19 @@ export const H5TemplateDrawer = ({ const [inputVisible, setInputVisible] = useState<{ [key: string]: boolean }>({}); const [isBottomExpanded, setIsBottomExpanded] = useState(true); const [isDescExpanded, setIsDescExpanded] = useState(false); + // 自由输入框布局 + const [freeInputLayout, setFreeInputLayout] = useState('bottom'); + + // 自由输入框布局 + useEffect(() => { + if (selectedTemplate?.storyRole && selectedTemplate.storyRole.length > 0 || + selectedTemplate?.storyItem && selectedTemplate.storyItem.length > 0 + ) { + setFreeInputLayout('bottom'); + } else { + setFreeInputLayout('top'); + } + }, [selectedTemplate]) useEffect(() => { if (isOpen) { @@ -115,9 +128,10 @@ export const H5TemplateDrawer = ({ setSelectedTemplate(null); } } catch (error) { + console.log("Failed to create story action:", error); + window.msg.error(error instanceof Error ? error.message : "Failed to create story action"); setIsTemplateCreating(false); setLocalLoading(0); - setSelectedTemplate(null); } finally { setLocalLoading(0); if (timer) clearInterval(timer); @@ -488,23 +502,50 @@ export const H5TemplateDrawer = ({ {renderRoles()} {renderItems()} + {/** 自由输入文字 */} + {freeInputLayout === 'top' && selectedTemplate?.freeInput && selectedTemplate.freeInput.length > 0 && ( +
+

+ input Configuration +

+