人脸识别与大模型问答

This commit is contained in:
jiang 2024-08-24 16:16:40 +08:00
parent 6c7c1c7fb9
commit 460991d615
8 changed files with 218 additions and 104 deletions

View File

@ -550,7 +550,7 @@ export default {
} }
</script> </script>
<style vars="{{PicNum}}"> <style lang="scss" vars="{{PicNum}}">
@import url('./../../assets/styles/SurveillanceVideo.css'); @import url('./../../assets/styles/SurveillanceVideo.css');
#main { #main {

View File

@ -17,9 +17,9 @@
<div class="main-left-list"> <div class="main-left-list">
<div class="list-group"> <div class="list-group">
<div <div
:class="windowId === item.windowId ? 'group-item group-item-selected':'group-item group-item-noSelected'" :class="windowId == item.windowId ? 'group-item group-item-selected':'group-item group-item-noSelected'"
v-for="(item, index) in windowList" :key="index"> v-for="(item, index) in windowList" :key="index" @mousedown="switchWindow(item.windowId)">
<span @click="switchWindow(item.windowId)">{{ item.windowName }}</span> <span>{{ item.windowName }}</span>
<i <i
class="el-icon-delete" @click="deleteChatWindow(item.windowId)" class="el-icon-delete" @click="deleteChatWindow(item.windowId)"
></i> ></i>
@ -29,7 +29,7 @@
</div> </div>
<div class="main-right"> <div class="main-right">
<div class="main-right-top"> <div class="main-right-top">
<div class="main-right-top-body"> <div class="main-right-top-body" ref="messageContainer">
<div class="main" v-for="(item, index) in answerList" :key="index"> <div class="main" v-for="(item, index) in answerList" :key="index">
<div class="problem"> <div class="problem">
<div class="icon"> <div class="icon">
@ -43,8 +43,8 @@
<div class="icon"> <div class="icon">
<img src="../../assets/images/answer.png" alt=""/> <img src="../../assets/images/answer.png" alt=""/>
</div> </div>
<div class="content"> <div class="content" v-html="item.answer">
<span>{{ item.answer }}</span> <!-- <span>{{ item.answer }}</span>-->
</div> </div>
</div> </div>
</div> </div>
@ -67,135 +67,246 @@
</div> </div>
</template> </template>
<script> <script>
import boxHeader from '@/views/components/boxHeader.vue' import boxHeader from '@/views/components/boxHeader.vue';
import dialogue from '@/views/askRequest/dialogue.vue' import dialogue from '@/views/askRequest/dialogue.vue';
import diagHistory from '@/views/askRequest/diagHistory.vue' import diagHistory from '@/views/askRequest/diagHistory.vue';
import { import {
deleteChatWindow, deleteChatWindow,
getAllByWindowId, getAllByWindowId,
getList, getList,
insertChatWindow, insertChatWindow,
insertQuestionAnswer, insertQuestionAnswer
knowledgeBaseChat } from '@/api/askRequest/askRequest';
} from '@/api/askRequest/askRequest' import {v4 as uuidv4} from 'uuid';
import faceListShowPic from "@/views/updateFace/faceListShowPic.vue";
export default { export default {
//
components: { components: {
boxHeader, boxHeader,
dialogue, dialogue,
diagHistory diagHistory
}, },
//
data() { data() {
return { return {
controller: '', controller: new AbortController(), // Fetch
windowId: '', windowId: '', // ID
windowList: [], windowList: [], //
answerList: [], answerList: [], //
inputValue: '', inputValue: '', //
isSearch: false, isAncestor: false
value: '', };
diagContentTmpMain: ''
}
}, },
//
mounted() {
//this.getList(); //
this.loadLastWindowId(); // 访ID
},
//
created() { created() {
this.controller = new AbortController(); this.getList(); //
this.getList();
}, },
// windowId
watch: { watch: {
windowId(val) { windowId(newWindowId) {
if (val) { this.getAllByWindowId(newWindowId);
this.getAllByWindowId(val);
}
} }
}, },
methods: { methods: {
// ID
generateNewWindowId() {
const lastWindowId = uuidv4().replace(/-/g, "");
this.windowId = lastWindowId
localStorage.setItem('lastWindowId', lastWindowId);// UUID-
},
// 访ID
loadLastWindowId() {
const lastWindowId = localStorage.getItem('lastWindowId'); // 使ID
if (lastWindowId) {
this.windowId = lastWindowId; // ID
} else {
this.generateNewWindowId(); // ID
}
},
// ID
switchWindow(windowId) {
if (this.isAncestor) {
this.$message.warning("问答进行中");
return;
}
localStorage.setItem('lastWindowId', windowId); // ID
this.windowId = windowId; // ID
},
//
getList() { getList() {
getList().then(res => { getList().then(res => {
if (res.code === 200) { if (res.code === 200) {
this.windowList = res.data; this.windowList = res.data; //
if (res.data.length > 0) { if (this.windowList.length === 0) {
this.windowId = res.data[0].windowId; this.generateNewWindowId();
this.answerList = []; //
} }
} }
}) });
},
switchWindow(windowId) {
this.windowId = windowId;
}, },
// ID
getAllByWindowId(windowId) { getAllByWindowId(windowId) {
getAllByWindowId(windowId).then(res => { getAllByWindowId(windowId).then(res => {
if (res.code === 200) { if (res.code === 200) {
this.answerList = res.data; this.answerList = res.data; //
this.scrollToBottom(); //
} }
}) });
}, },
//
deleteChatWindow(windowId) { deleteChatWindow(windowId) {
if (this.isAncestor) {
this.$message.warning("问答进行中");
return;
}
deleteChatWindow(windowId).then(res => { deleteChatWindow(windowId).then(res => {
if (res.code === 200) { if (res.code === 200) {
this.$message.success("删除成功"); this.$message.success("删除成功"); //
this.getList(); this.getList(); //
} }
}) });
}, },
insertChatWindow() {
if (!this.windowId) {
this.$message.warning("已经是最新窗口");
}
this.windowId = '';
this.answerList = [];
},
submitInput() {
if (!this.windowId) {
insertChatWindow({windowName: this.inputValue}).then(res => {
if (res.code === 200) {
this.getList();
}
})
}
insertQuestionAnswer().then(res => {
if (res.code === 200) {
this.getList();
}
})
this.resAnswer(this.inputValue)
this.inputValue = ""; //
},
async resAnswer(question) {
let params = {
"query": question,
"knowledge_base_name": "lzh",
"top_k": 6,
"score_threshold": 1,
"stream": true,
}
knowledgeBaseChat(params).then(response => {
const reader = response.data.getReader();
function read() { //
reader.read().then(({done, value}) => { insertChatWindow() {
if (done) { this.generateNewWindowId();
console.log('Stream complete'); this.answerList = [];// ID
return; },
//
submitInput() {
if (this.answerList.length === 0) {
//
insertChatWindow({windowName: this.inputValue, windowId: this.windowId}).then(res => {
if (res.code === 200) {
this.getList(); //
}
});
}
this.resAnswer(this.inputValue); //
this.inputValue = ""; //
},
//
scrollToBottom() {
this.$nextTick(() => {
const container = this.$refs.messageContainer; //
if (container) {
container.scrollTop = container.scrollHeight; //
}
});
},
//
async resAnswer(question) {
this.isAncestor = true;
//
const data = {
answer: "正在思考。。。", //
question: question, //
windowId: this.windowId, // ID
};
this.answerList.push(data); //
this.scrollToBottom(); //
const params = {
query: question, //
knowledge_base_name: 'lzh', // 使
stream: true, //
};
try {
// Fetch
const signal = this.controller.signal;
const response = await fetch('/api/chat/knowledge_base_chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params), // JSON
signal: signal, //
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`); //
}
const reader = response.body.getReader(); //
const decoder = new TextDecoder(); // TextDecoder
//
this.answerList[this.answerList.length - 1].answer = "";
while (true) {
const {done, value} = await reader.read(); //
if (done) break; //
const decodedValue = decoder.decode(value); //
//
const messages = decodedValue.split('}{').map((msg, index, array) => {
if (index !== 0) msg = '{' + msg;
if (index !== array.length - 1) msg += '}';
return msg;
});
//
messages.forEach((msg) => {
try {
const json = JSON.parse(msg);
if (json.answer) {
this.answerList[this.answerList.length - 1].answer += this.escapeHtml(json.answer); //
}
} catch (e) {
console.error('JSON parse error:', e); //
} }
//
console.log(new TextDecoder("utf-8").decode(value));
//
read();
}); });
} }
read(); //
}).catch(error => { insertQuestionAnswer(this.answerList[this.answerList.length - 1]).then(res => {
console.error('Error:', error); this.isAncestor = false;
}); })
} catch (error) {
console.error('Fetch error:', error); //
}
},
escapeHtml(str) {
// 使
return str.replace(/[&<>"']/g, (match) => {
switch (match) {
case '&':
return '&amp;';
case '<':
return '&lt;';
case '>':
return '&gt;';
case '"':
return '&quot;';
case "'":
return '&#39;';
}
})
} }
} }
} }
</script> </script>
<style scoped> <style lang="scss">
.main { .main {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@ -51,7 +51,7 @@ export default {
} }
</script> </script>
<style scoped> <style lang="scss">
#main { #main {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@ -54,6 +54,8 @@
<script> <script>
import {updateFace} from '@/api/updateFace/updateFace' import {updateFace} from '@/api/updateFace/updateFace'
import midPic from "@/views/updateFace/midPic.vue";
import faceListShowPic from "@/views/updateFace/faceListShowPic.vue";
const validationRules = { const validationRules = {
name: [ name: [
@ -98,6 +100,7 @@ export default {
watch: { watch: {
value(val) { value(val) {
this.visible = val; this.visible = val;
this.$emit('visible-change', val);
if (val) { if (val) {
this.resetParameters(); // this.resetParameters(); //
} }
@ -142,7 +145,9 @@ export default {
}); });
}, },
close() { close() {
this.$emit('input', false); faceListShowPic.methods.getList();
this.visible = false;
this.$emit('input', this.visible);
}, },
confirm() { confirm() {
this.close(); this.close();
@ -161,7 +166,7 @@ export default {
}; };
</script> </script>
<style scoped> <style lang="scss">
.modal-overlay { .modal-overlay {
z-index: 1000; z-index: 1000;
position: fixed; position: fixed;

View File

@ -2,7 +2,7 @@
<div class="body-container"> <div class="body-container">
<div class="content"> <div class="content">
<div class="face_img" v-for="(item, index) in faceList" :key="index"> <div class="face_img" v-for="(item, index) in faceList" :key="index">
<img :src="item.faceAddress" class="face_img" alt="">/> <img :src="'http://127.0.0.1:9300/'+item.faceAddress" class="face_img" alt="">/>
</div> </div>
</div> </div>
</div> </div>
@ -37,7 +37,7 @@ export default {
} }
</script> </script>
<style scoped> <style lang="scss">
/* 隐藏滚动条 */ /* 隐藏滚动条 */
.content::-webkit-scrollbar { .content::-webkit-scrollbar {
display: none; display: none;

View File

@ -59,7 +59,7 @@
<div class="bottom-right-content"> <div class="bottom-right-content">
<img <img
v-if="faceUrl" v-if="faceUrl"
:src="faceUrl" :src="'http://127.0.0.1:9300/'+faceUrl"
class="avatar" class="avatar"
alt="Avatar" alt="Avatar"
/> />
@ -74,7 +74,7 @@
</div> </div>
</div> </div>
</div> </div>
<addFace v-model="showModal" title="添加人脸" width="500px" @confirm="onConfirm"> <addFace v-model="showModal" title="添加人脸" width="500px" @visible-change="handleVisibleChange">
<p>这是弹窗的内容</p> <p>这是弹窗的内容</p>
</addFace> </addFace>
--> -->
@ -101,10 +101,9 @@ export default {
}, },
watch: { watch: {
showModal(val) { showModal(val) {
if (!val){ /* if (!val) {
faceListShowPic.methods.getList(); faceListShowPic.methods.getList();
} }*/
} }
}, },
methods: { methods: {
@ -125,10 +124,9 @@ export default {
}, },
update() { update() {
this.showModal = true this.showModal = true
}, },
onConfirm() { handleVisibleChange(newVal) {
this.showModal = newVal;
}, },
selectFile() { selectFile() {
this.$refs.fileInput.click(); this.$refs.fileInput.click();
@ -144,7 +142,7 @@ export default {
} }
</script> </script>
<style scoped> <style lang="scss">
@keyframes moveandflash { @keyframes moveandflash {
0%, 100% { 0%, 100% {

View File

@ -207,7 +207,7 @@ export default {
} }
</script> </script>
<style scoped> <style lang="scss">
#main { #main {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@ -40,7 +40,7 @@ module.exports = {
['^' + process.env.VUE_APP_BASE_API]: '' ['^' + process.env.VUE_APP_BASE_API]: ''
} }
}, },
"/dev-api/api": { "/api": {
"target": "http://192.168.0.21:17861", "target": "http://192.168.0.21:17861",
//设置允许跨域——此处我经过测试发现可有可无 //设置允许跨域——此处我经过测试发现可有可无
"changeOrigin": true, "changeOrigin": true,