diff --git a/src/oc-community-frontend/src/components/ChatWindow.vue b/src/oc-community-frontend/src/components/ChatWindow.vue index 46aac4d..3aefd08 100644 --- a/src/oc-community-frontend/src/components/ChatWindow.vue +++ b/src/oc-community-frontend/src/components/ChatWindow.vue @@ -113,13 +113,70 @@ const handleSend = async () => { return } try { - // 构造人设prompt + // 构造人设 prompt(与 OC 问卷字段一一对应,确保 AI 能获取完整人设) let persona = '' if (props.activeContact) { - persona += `你是${props.activeContact.name},`; - if (props.activeContact.occupation) persona += `职业:${props.activeContact.occupation},`; - if (props.activeContact.personality && props.activeContact.personality.length) persona += `性格:${Array.isArray(props.activeContact.personality) ? props.activeContact.personality.join('、') : props.activeContact.personality},`; - if (props.activeContact.bio) persona += `简介:${props.activeContact.bio},`; + const c = props.activeContact + const safe = (v) => (v === null || v === undefined) ? '' : String(v).replace(/\s+/g, ' ').trim() + const fmtList = (v) => Array.isArray(v) ? v.join('、') : (v ? safe(v) : '') + + persona += `你是${safe(c.name) || '该角色'}。`; + + // 以下字段按问卷顺序列出,标签使用中文与问卷保持一致 + const fields = [ + ['性别', c.gender || (c.genderOther ? c.genderOther : '')], + ['生日', c.birthday], + ['年龄', c.age], + ['种族', c.race], + ['职业', c.occupation], + ['发型与发色', c.hair], + ['瞳色', c.eyeColor], + ['身高', c.height], + ['着装风格', c.clothes], + ['标志性特征', c.feature], + ['核心性格', fmtList(c.personality) || c.personalityOther], + ['MBTI', c.mbti], + ['优点', c.advantage], + ['缺点', c.shortcoming], + ['习惯性小动作', c.habit], + ['口头禅', c.catchphrase], + ['成长环境', c.growup], + ['背景故事', c.story], + ['秘密', c.secret], + ['兴趣爱好', fmtList(c.hobbies)], + ['喜欢的食物', c.foodLike], + ['讨厌的东西', c.hate], + ['理想生活方式', c.life], + ['周末日常', c.weekend], + ['社区主要活动', c.communityActivity], + ['关系期待', fmtList(c.relation) || c.relationOther], + ['头像URL', c.avatar] + ] + + fields.forEach(([label, value]) => { + if (value || value === 0) { + persona += `${label}:${safe(value)};` + } + }) + + // 社交圈与成就(作为附加信息) + if (c.socialCircle && c.socialCircle.length) persona += `社交圈:${c.socialCircle.slice(0,5).map(x => x.name || x).join('、')};`; + if (c.achievements && c.achievements.length) persona += `成就:${c.achievements.slice(0,5).join('、')};`; + + // 今日行程简要(取当天日程并格式化为 时间-活动@地点) + try { + const now = new Date() + const todayStr = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0') + if (Array.isArray(c.schedule)) { + const todays = c.schedule.filter(s => String(s.date).startsWith(todayStr)) + if (todays.length) { + const brief = todays.slice(0,6).map(s => `${s.time || '--:--'}-${(s.event||'').slice(0,20)}@${s.location||''}`) + persona += `今日日程(简要):${brief.join(';')};`; + } + } + } catch (e) { + // ignore + } } // 共享用户信息给AI if (currentUser.value && currentUser.value.nickname) { @@ -127,7 +184,7 @@ const handleSend = async () => { if (currentUser.value.occupation) persona += `对方职业:${currentUser.value.occupation},`; if (currentUser.value.hobbies) persona += `对方爱好:${currentUser.value.hobbies},`; } - persona += '请用简洁、贴近生活的语气,只回复一句符合自己人设的聊天内容,不要多余解释。'; + persona += '请用简洁、贴近生活的语气,只回复一句符合自己人设和性格的聊天内容,如果对方没说就不要刻意强调自己知晓对方的爱好,不要混淆对方和自己的爱好,回复的文本长度根据对方的语句进行调整,比如对方只是简单问候就可以简短回应,对于问题则可以以自身人设风格进行较为详细的解答。'; const prompt = `${persona}\n对方说:${userText}`; const res = await axios.post( 'https://open.bigmodel.cn/api/paas/v4/chat/completions', diff --git a/src/oc-community-frontend/src/components/CommunityPage.vue b/src/oc-community-frontend/src/components/CommunityPage.vue index 3254350..30800aa 100644 --- a/src/oc-community-frontend/src/components/CommunityPage.vue +++ b/src/oc-community-frontend/src/components/CommunityPage.vue @@ -230,7 +230,7 @@ const closePopoverOnClickOutside = (event) => { .community-container { display: flex; height: 100vh; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background: linear-gradient(135deg, #ffc6c6 0%, #7486c0 100%); position: relative; overflow: hidden; } diff --git a/src/oc-community-frontend/src/components/OCCreationPage.vue b/src/oc-community-frontend/src/components/OCCreationPage.vue index 268def1..4b9be96 100644 --- a/src/oc-community-frontend/src/components/OCCreationPage.vue +++ b/src/oc-community-frontend/src/components/OCCreationPage.vue @@ -206,8 +206,8 @@ const handleAIGenerate = async () => { ElMessage.info('AI生成中...') const API_KEY = import.meta.env.VITE_ZHIPU_API_KEY const prompt = `生成一个OC角色的JSON对象,字段有: -name, gender, genderOther, birthday, age, race, occupation, hair, eyeColor, height, clothes, feature, personality(数组), personalityOther, mbti, advantage, shortcoming, habit, catchphrase, growup, story, secret, hobbies(数组), foodLike, hate, life, weekend, communityActivity, relation(数组), relationOther, avatar。 -每个字段都要有合理的虚构内容,随机性强,不要总生成相似的人设,必须为中文,其中birthday只有月日,如8-15,不能留空、不能为[]、不能为null。 +name, gender, genderOther, birthday, age, race, occupation, hair, eyeColor, height, clothes, feature, personality(数组), personalityOther, mbti, advantage, shortcoming, habit, catchphrase, growup, story, secret, hobbies(数组), foodLike, hate, life, weekend, communityActivity, relationOther。 +每个字段都要有合理的虚构内容,生成人设可以为现实、魔幻、二次元等风格,随机性强,不要总生成相似的人设,必须为中文,其中birthday只有月日,如8-15,不能留空、不能为[]、不能为null。 只输出JSON对象本身,不要任何推理、解释、reasoning、注释、代码块、markdown标记或多余内容。`; try { const res = await axios.post( @@ -342,7 +342,7 @@ const handleCancel = () => { justify-content: center; align-items: center; min-height: 100vh; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background: linear-gradient(135deg, #9ae1ff 0%, #ffbefa 100%); padding: 20px; } diff --git a/src/oc-community-frontend/开发日志.txt b/src/oc-community-frontend/开发日志.txt index 44931af..bba7702 100644 --- a/src/oc-community-frontend/开发日志.txt +++ b/src/oc-community-frontend/开发日志.txt @@ -182,11 +182,13 @@ oc问卷ai随机生成成功实现,但创建oc数量好像有最大限制, 将社区地图图片替换成map,社区地点上方有坐标点,地点名称,所在人数(根据所有oc的日程表中,与现实时间相比较,在同一天且相差时间最少的时间点的活动地点与当前地点一致,则判断该oc当前在这个地点),点击坐标点后显示所在的oc头像,点击对应oc头像可查看oc信息 日程表生成后要保存到数据库中,下次进入oc信息界面时可以直接显示,日程表在任何情况下显示时要与最近一次生成内容保持同步 0.1.5 -点击对应oc头像可查看oc信息 +社区地图的地点弹窗中点击对应oc头像可查看oc信息--界面跳转 +手机中点资料可以查看oc信息,聊天窗口增加状态栏,实时显示oc活动状态;ai根据日程状态,延时回复(比如oc当前正在休闲放松可以实时回复,若进行体育运动如游泳就要延时回复) +修改个人昵称;不同用户登录,地图上不显示非当前用户oc的活动--个人信息与oc日程信息关联 +导入地区地图和实时天气,并显示在社区地图界面中--一种尝试 +ai生成oc头像--AI绘图 - - -导入地区地图和实时天气,并显示在社区地图界面中 +##ai记忆聊天历史,并根据聊天历史进行回复;迁移数据库 自主构建地图 --0.2目标:成功调用ai,搭建基本社区地图