人脸识别与大模型问答

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>
<style vars="{{PicNum}}">
<style lang="scss" vars="{{PicNum}}">
@import url('./../../assets/styles/SurveillanceVideo.css');
#main {

View File

@ -17,9 +17,9 @@
<div class="main-left-list">
<div class="list-group">
<div
:class="windowId === item.windowId ? 'group-item group-item-selected':'group-item group-item-noSelected'"
v-for="(item, index) in windowList" :key="index">
<span @click="switchWindow(item.windowId)">{{ item.windowName }}</span>
:class="windowId == item.windowId ? 'group-item group-item-selected':'group-item group-item-noSelected'"
v-for="(item, index) in windowList" :key="index" @mousedown="switchWindow(item.windowId)">
<span>{{ item.windowName }}</span>
<i
class="el-icon-delete" @click="deleteChatWindow(item.windowId)"
></i>
@ -29,7 +29,7 @@
</div>
<div class="main-right">
<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="problem">
<div class="icon">
@ -43,8 +43,8 @@
<div class="icon">
<img src="../../assets/images/answer.png" alt=""/>
</div>
<div class="content">
<span>{{ item.answer }}</span>
<div class="content" v-html="item.answer">
<!-- <span>{{ item.answer }}</span>-->
</div>
</div>
</div>
@ -67,135 +67,246 @@
</div>
</template>
<script>
import boxHeader from '@/views/components/boxHeader.vue'
import dialogue from '@/views/askRequest/dialogue.vue'
import diagHistory from '@/views/askRequest/diagHistory.vue'
import boxHeader from '@/views/components/boxHeader.vue';
import dialogue from '@/views/askRequest/dialogue.vue';
import diagHistory from '@/views/askRequest/diagHistory.vue';
import {
deleteChatWindow,
getAllByWindowId,
getList,
insertChatWindow,
insertQuestionAnswer,
knowledgeBaseChat
} from '@/api/askRequest/askRequest'
import faceListShowPic from "@/views/updateFace/faceListShowPic.vue";
insertQuestionAnswer
} from '@/api/askRequest/askRequest';
import {v4 as uuidv4} from 'uuid';
export default {
//
components: {
boxHeader,
dialogue,
diagHistory
},
//
data() {
return {
controller: '',
windowId: '',
windowList: [],
answerList: [],
inputValue: '',
isSearch: false,
value: '',
diagContentTmpMain: ''
}
controller: new AbortController(), // Fetch
windowId: '', // ID
windowList: [], //
answerList: [], //
inputValue: '', //
isAncestor: false
};
},
//
mounted() {
//this.getList(); //
this.loadLastWindowId(); // 访ID
},
//
created() {
this.controller = new AbortController();
this.getList();
this.getList(); //
},
// windowId
watch: {
windowId(val) {
if (val) {
this.getAllByWindowId(val);
}
windowId(newWindowId) {
this.getAllByWindowId(newWindowId);
}
},
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().then(res => {
if (res.code === 200) {
this.windowList = res.data;
if (res.data.length > 0) {
this.windowId = res.data[0].windowId;
this.windowList = res.data; //
if (this.windowList.length === 0) {
this.generateNewWindowId();
this.answerList = []; //
}
}
})
},
switchWindow(windowId) {
this.windowId = windowId;
});
},
// ID
getAllByWindowId(windowId) {
getAllByWindowId(windowId).then(res => {
if (res.code === 200) {
this.answerList = res.data;
this.answerList = res.data; //
this.scrollToBottom(); //
}
})
});
},
//
deleteChatWindow(windowId) {
if (this.isAncestor) {
this.$message.warning("问答进行中");
return;
}
deleteChatWindow(windowId).then(res => {
if (res.code === 200) {
this.$message.success("删除成功");
this.getList();
this.$message.success("删除成功"); //
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}) => {
if (done) {
console.log('Stream complete');
return;
//
insertChatWindow() {
this.generateNewWindowId();
this.answerList = [];// ID
},
//
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 => {
console.error('Error:', error);
});
//
insertQuestionAnswer(this.answerList[this.answerList.length - 1]).then(res => {
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>
<style scoped>
<style lang="scss">
.main {
width: 100%;
height: 100%;

View File

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

View File

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

View File

@ -2,7 +2,7 @@
<div class="body-container">
<div class="content">
<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>
@ -37,7 +37,7 @@ export default {
}
</script>
<style scoped>
<style lang="scss">
/* 隐藏滚动条 */
.content::-webkit-scrollbar {
display: none;

View File

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

View File

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

View File

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