|
@@ -5,20 +5,34 @@
|
|
|
<van-icon name="arrow-left" size="16" />
|
|
|
</div>
|
|
|
|
|
|
- <van-button type="primary" size="small" @click="generateProject">开始AI生成工程</van-button>
|
|
|
+ <div class="clear-btn" @click="clearMsg">清空</div>
|
|
|
</div>
|
|
|
|
|
|
- <van-field
|
|
|
- v-model="msg"
|
|
|
- rows="8"
|
|
|
- autosize
|
|
|
- type="textarea"
|
|
|
- maxlength="500"
|
|
|
- placeholder="请输入您要编程的内容"
|
|
|
- show-word-limit
|
|
|
- />
|
|
|
-
|
|
|
- <div class="tip">新生成的工程会覆盖原工程,请做好保存。</div>
|
|
|
+ <div class="msg-list" ref="msgListRef">
|
|
|
+ <div class="msg-item" v-for="item in crtProject?.msgList" :class="item.role === 'user' ? 'r' : 'l'">
|
|
|
+ {{ item.content }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="chat-box">
|
|
|
+ <div class="toolbar">
|
|
|
+ <div class="deep-think" @click="deepThink">深度思考</div>
|
|
|
+ </div>
|
|
|
+ <div class="input-box">
|
|
|
+ <van-cell-group inset>
|
|
|
+ <van-field
|
|
|
+ v-model="msg"
|
|
|
+ rows="1"
|
|
|
+ autosize
|
|
|
+ type="textarea"
|
|
|
+ maxlength="500"
|
|
|
+ placeholder="请输入您要编程的内容"
|
|
|
+ />
|
|
|
+ </van-cell-group>
|
|
|
+ <div class="send-btn" @click="generateProject">
|
|
|
+ <van-icon size="32" name="upgrade" color="#1989fa" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -38,8 +52,8 @@ watch(
|
|
|
() => route,
|
|
|
() => {
|
|
|
crtProject.value = projectList.value.find((item) => item.id === route.query.id)
|
|
|
- if (crtProject.value?.type === 'AI') {
|
|
|
- msg.value = crtProject.value.prompt
|
|
|
+ if (!crtProject.value?.msgList) {
|
|
|
+ crtProject.value!.msgList = []
|
|
|
}
|
|
|
},
|
|
|
{
|
|
@@ -49,36 +63,75 @@ watch(
|
|
|
}
|
|
|
)
|
|
|
|
|
|
+const msgListRef = ref<HTMLDivElement>()
|
|
|
+
|
|
|
+watch(crtProject.value!.msgList, () => {
|
|
|
+ nextTick(() => {
|
|
|
+ msgListRef.value?.scrollTo({
|
|
|
+ top: msgListRef.value?.scrollHeight,
|
|
|
+ behavior: 'smooth'
|
|
|
+ })
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+const clearMsg = () => {
|
|
|
+ crtProject.value!.msgList = []
|
|
|
+}
|
|
|
+
|
|
|
+const deepThink = () => {
|
|
|
+ showSuccessToast('敬请期待')
|
|
|
+}
|
|
|
+
|
|
|
const generateProject = async () => {
|
|
|
+ if (!msg.value) return
|
|
|
const loading = showLoadingToast({
|
|
|
message: '正在生成中...',
|
|
|
forbidClick: true,
|
|
|
duration: 0
|
|
|
})
|
|
|
- let prompt = ''
|
|
|
- if (crtProject.value?.type === 'default') {
|
|
|
- prompt = `这是当前工程的内容,请根据这个内容重新生成工程:${JSON.stringify(crtProject.value)},并满足以下要求:`
|
|
|
+ crtProject.value?.msgList.push({
|
|
|
+ role: 'user',
|
|
|
+ content: msg.value
|
|
|
+ })
|
|
|
+ const params: any = {}
|
|
|
+ for (let i = crtProject.value!.msgList.length - 1; i >= 0; i--) {
|
|
|
+ if (crtProject.value!.msgList[i].role === 'assistant' && crtProject.value!.msgList[i].session_id !== '') {
|
|
|
+ const timeDiff = Date.now() - crtProject.value!.msgList[i].timestamp!
|
|
|
+ if (timeDiff >= 60 * 60 * 1000) {
|
|
|
+ // 超时
|
|
|
+ params.messages = crtProject.value!.msgList.map((item) => {
|
|
|
+ return { role: item.role, content: item.role === 'user' ? item.content : item.result }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ params.session_id = crtProject.value!.msgList[i].session_id
|
|
|
+ params.prompt = msg.value
|
|
|
+ }
|
|
|
+ break
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- const res = await fetch('http://127.0.0.1:3000/api/chat', {
|
|
|
+ msg.value = ''
|
|
|
+ const res = await fetch('https://plceditor.worldflying.cn/api/ai/chat', {
|
|
|
method: 'POST',
|
|
|
headers: {
|
|
|
'Content-Type': 'application/json'
|
|
|
},
|
|
|
- body: JSON.stringify({
|
|
|
- msg: prompt + msg.value
|
|
|
- })
|
|
|
+ body: JSON.stringify(params)
|
|
|
}).then((res) => res.json())
|
|
|
console.log(res)
|
|
|
if (res.errcode === '1001') {
|
|
|
showFailToast('操作失败!')
|
|
|
} else {
|
|
|
- if (res.data === '请正确描述您要编程的内容') {
|
|
|
+ if (res.output.text === '请正确描述您要编程的内容。' || res.output.text === '请正确描述您要编程的内容') {
|
|
|
loading.close()
|
|
|
- showFailToast('请正确描述您要编程的内容')
|
|
|
+ // showFailToast('请正确描述您要编程的内容')
|
|
|
+ crtProject.value!.msgList.push({
|
|
|
+ role: 'assistant',
|
|
|
+ content: '请正确描述您要编程的内容',
|
|
|
+ result: res.output.text
|
|
|
+ })
|
|
|
} else {
|
|
|
try {
|
|
|
- let jsonData = res.data
|
|
|
+ let jsonData = res.output.text
|
|
|
if (jsonData.slice(0, 8).includes('json')) {
|
|
|
jsonData = jsonData.slice(8).slice(0, -3)
|
|
|
}
|
|
@@ -88,13 +141,23 @@ const generateProject = async () => {
|
|
|
console.log(project)
|
|
|
// console.log(p)
|
|
|
crtProject.value!.commandList = project.commandList
|
|
|
- crtProject.value!.prompt = msg.value
|
|
|
-
|
|
|
+ crtProject.value!.msgList.push({
|
|
|
+ role: 'assistant',
|
|
|
+ content: '生成成功,请返回工程界面查看生成结果。',
|
|
|
+ session_id: res.output.session_id,
|
|
|
+ timestamp: Date.now(),
|
|
|
+ result: res.output.text
|
|
|
+ })
|
|
|
loading.close()
|
|
|
showSuccessToast('操作成功!')
|
|
|
} catch (error) {
|
|
|
loading.close()
|
|
|
- showFailToast('操作失败!')
|
|
|
+ // showFailToast('操作失败!')
|
|
|
+ crtProject.value!.msgList.push({
|
|
|
+ role: 'assistant',
|
|
|
+ content: '生成失败。',
|
|
|
+ result: res.output.text
|
|
|
+ })
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -105,6 +168,7 @@ const generateProject = async () => {
|
|
|
.ai-main {
|
|
|
height: 100%;
|
|
|
background: #fff;
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
|
.header {
|
|
|
display: flex;
|
|
@@ -116,4 +180,65 @@ const generateProject = async () => {
|
|
|
padding: 16px;
|
|
|
color: #ccc;
|
|
|
}
|
|
|
+.clear-btn {
|
|
|
+ color: #1989fa;
|
|
|
+}
|
|
|
+
|
|
|
+.msg-list {
|
|
|
+ padding: 16px;
|
|
|
+ height: calc(100% - 172px);
|
|
|
+ overflow: auto;
|
|
|
+}
|
|
|
+.msg-list .msg-item {
|
|
|
+ padding: 12px;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ border-radius: 8px;
|
|
|
+ background: #f5f5f5;
|
|
|
+ max-width: 80%;
|
|
|
+ width: max-content;
|
|
|
+ line-height: 1;
|
|
|
+}
|
|
|
+.msg-list .msg-item.r {
|
|
|
+ background: #1989fa;
|
|
|
+ color: #fff;
|
|
|
+ margin-left: auto;
|
|
|
+}
|
|
|
+.msg-list .msg-item.l {
|
|
|
+ color: #333;
|
|
|
+ margin-right: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-box {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ background-color: #fff;
|
|
|
+}
|
|
|
+.chat-box .toolbar {
|
|
|
+ padding: 8px 16px 0;
|
|
|
+}
|
|
|
+.chat-box .toolbar .deep-think {
|
|
|
+ border: 1px solid #ccc;
|
|
|
+ border-radius: 8px;
|
|
|
+ font-size: 14px;
|
|
|
+ width: max-content;
|
|
|
+ padding: 8px;
|
|
|
+ box-shadow: 0 0 1px #ddd;
|
|
|
+ line-height: 1;
|
|
|
+}
|
|
|
+.chat-box .input-box {
|
|
|
+ margin: 12px 16px;
|
|
|
+ padding: 4px;
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ align-items: center;
|
|
|
+ box-shadow: 0 0 4px 2px #ddd;
|
|
|
+ border-radius: 16px;
|
|
|
+ height: auto;
|
|
|
+}
|
|
|
+.chat-box .input-box .van-cell-group {
|
|
|
+ flex: 1;
|
|
|
+ margin: 0;
|
|
|
+}
|
|
|
</style>
|