人脸识别与大模型问答
This commit is contained in:
parent
460991d615
commit
fcfa7fcb02
|
|
@ -43,7 +43,7 @@ export default {
|
|||
this.currentTime = `${hours}:${minutes}:${seconds}`;
|
||||
},
|
||||
backToHome() {
|
||||
this.$router.push('/largeScreen').then(() => {
|
||||
this.$router.push('/index').then(() => {
|
||||
localStorage.clear();
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { isRelogin } from '@/utils/request'
|
|||
|
||||
NProgress.configure({ showSpinner: false })
|
||||
|
||||
const whiteList = ['/login', '/updateFace','/largeScreen','/updateIDCard','/Violation','/Text','/Video','/askRequest','/radar']
|
||||
const whiteList = ['/login', '/updateFace','/index','/updateIDCard','/Violation','/Text','/Video','/askRequest','/radar']
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
NProgress.start()
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export const constantRoutes = [
|
|||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/largeScreen',
|
||||
path: '/index',
|
||||
component: () => import('@/views/largeScreen/largeScreen'),
|
||||
hidden: true
|
||||
},
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ export default {
|
|||
methods: {
|
||||
backToHome() {
|
||||
this.$router.beforeEach((to, from, next) => {
|
||||
if (from.path === '/largeScreen') {
|
||||
if (from.path === '/index') {
|
||||
// 清除缓存的操作
|
||||
// 可以使用 localStorage.clear() 或其他方法清除缓存
|
||||
localStorage.clear();
|
||||
|
|
@ -84,7 +84,7 @@ export default {
|
|||
});
|
||||
|
||||
// 跳转到主页
|
||||
this.$router.push('/largeScreen');
|
||||
this.$router.push('/index');
|
||||
},
|
||||
handup() {
|
||||
alert(1)
|
||||
|
|
|
|||
|
|
@ -175,7 +175,9 @@ export default {
|
|||
deleteChatWindow(windowId).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.$message.success("删除成功"); // 显示删除成功的提示信息
|
||||
this.getList(); // 重新获取窗口列表
|
||||
this.getList();
|
||||
/* this.answerList = [];*/
|
||||
this.generateNewWindowId();// 重新获取窗口列表
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
@ -188,6 +190,10 @@ export default {
|
|||
|
||||
// 提交输入内容
|
||||
submitInput() {
|
||||
if (this.isAncestor) {
|
||||
this.$message.warning("问答进行中");
|
||||
return;
|
||||
}
|
||||
if (this.answerList.length === 0) {
|
||||
// 如果当前窗口没有聊天记录,插入一个新的聊天窗口
|
||||
insertChatWindow({windowName: this.inputValue, windowId: this.windowId}).then(res => {
|
||||
|
|
|
|||
|
|
@ -42,15 +42,6 @@
|
|||
<div class="boxMidTwoc">
|
||||
<div class="boxMidLevelThreec">OCR识别</div>
|
||||
<div class="midIconMainc">
|
||||
<div class="midIconc">
|
||||
<a href="javascript:;" class="midIconLinkc">
|
||||
<img src="../../assets/images/midFiveIcon.png" alt="error" class="midIconLinkPicc"
|
||||
@click="goToViolation"></a>
|
||||
<div class="midTextc midTextFithc">发票识别</div>
|
||||
<div class="hatInsertc"><span class="bigTextc">{{ InvoiceNum }}</span><span
|
||||
class="smallTextc">(次)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="midIconc">
|
||||
<a href="javascript:;" class="midIconLinkc">
|
||||
<img src="../../assets/images/midSixIcon.png" alt="error" class="midIconLinkPicc"
|
||||
|
|
@ -60,6 +51,16 @@
|
|||
class="smallTextc">(次)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="midIconc">
|
||||
<a href="javascript:;" class="midIconLinkc">
|
||||
<img src="../../assets/images/midFiveIcon.png" alt="error" class="midIconLinkPicc"
|
||||
@click="goToViolation"></a>
|
||||
<div class="midTextc midTextFithc">发票识别</div>
|
||||
<div class="hatInsertc"><span class="bigTextc">{{ InvoiceNum }}</span><span
|
||||
class="smallTextc">(次)</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="midIconc ">
|
||||
<a href="javascript:;" class="midIconLinkc">
|
||||
<img src="../../assets/images/midSevenIcon.png" alt="error" class="midIconLinkPicc"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<div class="modal-body-left">
|
||||
<input
|
||||
type="file"
|
||||
accept="image/jpeg"
|
||||
accept="image/jpeg,image/png"
|
||||
style="display: none"
|
||||
ref="fileInput"
|
||||
@change="handleFileChange"
|
||||
|
|
@ -60,10 +60,32 @@ import faceListShowPic from "@/views/updateFace/faceListShowPic.vue";
|
|||
const validationRules = {
|
||||
name: [
|
||||
{required: true, message: '人员名称不能为空', trigger: 'blur'},
|
||||
{min: 2, max: 20, message: '用户名称长度必须介于 2 和 20 之间', trigger: 'blur'}
|
||||
{min: 2, max: 20, message: '用户名称长度必须介于 2 和 4 之间', trigger: 'blur'},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const chineseNamePattern = /^[\u4e00-\u9fa5]{2,4}$/;
|
||||
if (!chineseNamePattern.test(value)) {
|
||||
callback(new Error('姓名只能包含中文字符'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
idCardNumber: [
|
||||
{required: true, message: '人员身份证号不能为空', trigger: 'blur'}
|
||||
{required: true, message: '人员身份证号不能为空', trigger: 'blur'},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const idCardPattern = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[\dXx]$/;
|
||||
if (!idCardPattern.test(value)) {
|
||||
callback(new Error('身份证号码格式不正确'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
sex: [
|
||||
{required: true, message: '请选择性别', trigger: 'change'}
|
||||
|
|
@ -145,7 +167,6 @@ export default {
|
|||
});
|
||||
},
|
||||
close() {
|
||||
faceListShowPic.methods.getList();
|
||||
this.visible = false;
|
||||
this.$emit('input', this.visible);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,126 +1,130 @@
|
|||
<template>
|
||||
<div class="faceListResWatchBox">
|
||||
<img src="../../assets/images/resultHeader.png" alt="error" class="faceListResWatchPic">
|
||||
<table class="faceListResWatchTable">
|
||||
<thead>
|
||||
<tr class="faceListResWatchRow">
|
||||
<th class="faceListResWatchColume faceListResWatchColumeSort">序号</th>
|
||||
<th class="faceListResWatchColume faceListResWatchColumeIPAddr">访问地址</th>
|
||||
<th class="faceListResWatchColume faceListResWatchColumeDate">访问时间</th>
|
||||
<th class="faceListResWatchColume faceListResWatchColumeTime">响应时长</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in faceRecognition2" :key="index"
|
||||
:class="{ 'faceContentRowEven': index % 2 === 0, 'faceContentRowPrime': index % 2 !== 0 }">
|
||||
<td class="faceListResWatchColume faceListResWatchColumeSort">{{ index + 1 }}</td>
|
||||
<td class="faceListResWatchColume faceListResWatchColumeIPAddr">{{ item.ip }}</td>
|
||||
<td class="faceListResWatchColume faceListResWatchColumeDate">{{ item.returnTime }}</td>
|
||||
<td class="faceListResWatchColume faceListResWatchColumeTime">{{ item.responseTime }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="body-container">
|
||||
<table class="mian">
|
||||
<thead class="thead-dark">
|
||||
<tr class="faceListResWatchRow">
|
||||
<th class="faceListResWatchColume faceListResWatchColumeSort">序号</th>
|
||||
<th class="faceListResWatchColume faceListResWatchColumeIPAddr">访问地址</th>
|
||||
<th class="faceListResWatchColume faceListResWatchColumeDate">访问时间</th>
|
||||
<th class="faceListResWatchColume faceListResWatchColumeTime">响应时长</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in faceRecognition2" :key="index"
|
||||
:class="{ 'faceContentRowEven': index % 2 === 0, 'faceContentRowPrime': index % 2 !== 0 }">
|
||||
<td class="faceListResWatchColume faceListResWatchColumeSort">{{ index + 1 }}</td>
|
||||
<td class="faceListResWatchColume faceListResWatchColumeIPAddr">{{ item.ip }}</td>
|
||||
<td class="faceListResWatchColume faceListResWatchColumeDate">{{ item.returnTime }}</td>
|
||||
<td class="faceListResWatchColume faceListResWatchColumeTime">{{ item.responseTime }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'faceListResWatch',
|
||||
data(){
|
||||
return {
|
||||
faceRecognition2: [1,1,1,1,1,1,1,1,1,1,1],
|
||||
}
|
||||
name: 'faceListResWatch',
|
||||
data() {
|
||||
return {
|
||||
faceRecognition2: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mian {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column
|
||||
}
|
||||
|
||||
/* Firefox */
|
||||
html {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
/* IE 10+ */
|
||||
* {
|
||||
-ms-overflow-style: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.faceListResWatchBox {
|
||||
padding-left: 1.25rem;
|
||||
padding-right: 1.25rem;
|
||||
position: relative;
|
||||
padding-left: 1.25rem;
|
||||
padding-right: 1.25rem;
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
tbody {
|
||||
height: 14.5rem;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
scroll-behavior: smooth;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.faceListResWatchPic {
|
||||
width: 100%;
|
||||
height: 3.0625rem;
|
||||
width: 100%;
|
||||
height: 3.0625rem;
|
||||
}
|
||||
|
||||
.faceListResWatchTable {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.faceListResWatchRow {
|
||||
width: 100%;
|
||||
background: linear-gradient(to bottom, rgba(47, 47, 214, .6), rgba(255, 255, 255, .7));
|
||||
display: flex;
|
||||
height: 2.1rem;
|
||||
/* 底部边框为2像素宽的黑色边框 */
|
||||
width: 100%;
|
||||
background: linear-gradient(to bottom, rgba(47, 47, 214, .6), rgba(255, 255, 255, .7));
|
||||
display: flex;
|
||||
height: 2.1rem;
|
||||
/* 底部边框为2像素宽的黑色边框 */
|
||||
}
|
||||
|
||||
.faceListResWatchColume {
|
||||
font-size: 1rem;
|
||||
padding-top: .3rem;
|
||||
padding-bottom: .4rem;
|
||||
text-align: center;
|
||||
height: 2rem;
|
||||
color: #FFFFFF;
|
||||
font-size: 1rem;
|
||||
padding-top: .3rem;
|
||||
padding-bottom: .4rem;
|
||||
text-align: center;
|
||||
height: 2rem;
|
||||
color: #FFFFFF;
|
||||
|
||||
}
|
||||
|
||||
.faceContentRowPrime {
|
||||
background-color: RGBA(13, 31, 75, .8);
|
||||
display: flex;
|
||||
background-color: RGBA(13, 31, 75, .8);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.faceContentRowEven {
|
||||
background-color: RGBA(6, 19, 48, .9);
|
||||
display: flex;
|
||||
background-color: RGBA(6, 19, 48, .9);
|
||||
display: flex;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.faceListResWatchColumeSort {
|
||||
flex: 1
|
||||
flex: 1
|
||||
}
|
||||
|
||||
.faceListResWatchColumeIPAddr {
|
||||
/* border: #55636f 1px solid; */
|
||||
text-align: center;
|
||||
flex: 2
|
||||
/* border: #55636f 1px solid; */
|
||||
text-align: center;
|
||||
flex: 2
|
||||
}
|
||||
|
||||
.faceListResWatchColumeDate {
|
||||
/* border: #2f6ca2 1px solid; */
|
||||
flex: 2
|
||||
}
|
||||
|
||||
.faceListResWatchColumeTime {
|
||||
/* border: #530303 1px solid; */
|
||||
flex: 1
|
||||
/* border: #530303 1px solid; */
|
||||
flex: 1
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,126 +1,131 @@
|
|||
<template>
|
||||
<div class="faceListRecoResultBox">
|
||||
<img src="../../assets/images/resultHeader.png" alt="error" class="faceListRecoResultPic">
|
||||
<table class="faceListRecoResultTable">
|
||||
<thead>
|
||||
<tr class="faceListRecoResultRow">
|
||||
<th class="faceListRecoResultColume faceListRecoResultColumeSort">序号</th>
|
||||
<th class="faceListRecoResultColume faceListRecoResultColumeIPAddr">访问地址</th>
|
||||
<th class="faceListRecoResultColume faceListRecoResultColumeDate">访问时间</th>
|
||||
<th class="faceListRecoResultColume faceListRecoResultColumeTime">响应时长</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in faceRecognition" :key="index"
|
||||
:class="{ 'faceContentRowEven': index % 2 === 0, 'faceContentRowPrime': index % 2 !== 0 }">
|
||||
<td class="faceListRecoResultColume faceListRecoResultColumeSort">{{ index + 1 }}</td>
|
||||
<td class="faceListRecoResultColume faceListRecoResultColumeIPAddr">{{ item.ip }}</td>
|
||||
<td class="faceListRecoResultColume faceListRecoResultColumeDate">{{ item.returnTime }}</td>
|
||||
<td class="faceListRecoResultColume faceListRecoResultColumeTime">{{ item.responseTime }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="body-container">
|
||||
<table class="mian">
|
||||
<thead>
|
||||
<tr class="faceListRecoResultRow">
|
||||
<th class="faceListRecoResultColume faceListRecoResultColumeSort">序号</th>
|
||||
<th class="faceListRecoResultColume faceListRecoResultColumeIPAddr">访问地址</th>
|
||||
<th class="faceListRecoResultColume faceListRecoResultColumeDate">访问时间</th>
|
||||
<th class="faceListRecoResultColume faceListRecoResultColumeTime">响应时长</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in faceRecognition" :key="index"
|
||||
:class="{ 'faceContentRowEven': index % 2 === 0, 'faceContentRowPrime': index % 2 !== 0 }">
|
||||
<td class="faceListRecoResultColume faceListRecoResultColumeSort">{{ index + 1 }}</td>
|
||||
<td class="faceListRecoResultColume faceListRecoResultColumeIPAddr">{{ item.ip }}</td>
|
||||
<td class="faceListRecoResultColume faceListRecoResultColumeDate">{{ item.returnTime }}</td>
|
||||
<td class="faceListRecoResultColume faceListRecoResultColumeTime">{{ item.responseTime }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'faceListResultCount',
|
||||
data() {
|
||||
return {
|
||||
faceRecognition: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
}
|
||||
name: 'faceListResultCount',
|
||||
data() {
|
||||
return {
|
||||
faceRecognition: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mian {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column
|
||||
}
|
||||
|
||||
/* Firefox */
|
||||
html {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
/* IE 10+ */
|
||||
* {
|
||||
-ms-overflow-style: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.faceListRecoResultBox {
|
||||
padding-left: 1.25rem;
|
||||
padding-right: 1.25rem;
|
||||
position: relative;
|
||||
padding-left: 1.25rem;
|
||||
padding-right: 1.25rem;
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
.faceListRecoResultPic {
|
||||
width: 100%;
|
||||
height: 3.0625rem;
|
||||
width: 100%;
|
||||
height: 3.0625rem;
|
||||
}
|
||||
|
||||
.faceListRecoResultTable {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
|
||||
|
||||
}
|
||||
|
||||
tbody {
|
||||
height: 14.5rem;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
scroll-behavior: smooth;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
scroll-behavior: smooth;
|
||||
|
||||
}
|
||||
|
||||
.faceListRecoResultRow {
|
||||
width: 100%;
|
||||
background: linear-gradient(to bottom, rgba(47, 47, 214, .6), rgba(255, 255, 255, .7));
|
||||
display: flex;
|
||||
height: 2.1rem;
|
||||
/* 底部边框为2像素宽的黑色边框 */
|
||||
width: 100%;
|
||||
background: linear-gradient(to bottom, rgba(47, 47, 214, .6), rgba(255, 255, 255, .7));
|
||||
display: flex;
|
||||
height: 2.1rem;
|
||||
/* 底部边框为2像素宽的黑色边框 */
|
||||
}
|
||||
|
||||
.faceListRecoResultColume {
|
||||
font-size: 1rem;
|
||||
padding-top: .3rem;
|
||||
padding-bottom: .4rem;
|
||||
text-align: center;
|
||||
height: 2rem;
|
||||
color: #FFFFFF;
|
||||
font-size: 1rem;
|
||||
padding-top: .3rem;
|
||||
padding-bottom: .4rem;
|
||||
text-align: center;
|
||||
height: 2rem;
|
||||
color: #FFFFFF;
|
||||
|
||||
}
|
||||
|
||||
.faceContentRowPrime {
|
||||
background-color: RGBA(13, 31, 75, .8);
|
||||
display: flex;
|
||||
background-color: RGBA(13, 31, 75, .8);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.faceContentRowEven {
|
||||
background-color: RGBA(6, 19, 48, .9);
|
||||
display: flex;
|
||||
background-color: RGBA(6, 19, 48, .9);
|
||||
display: flex;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.faceListRecoResultColumeSort {
|
||||
flex: 1
|
||||
flex: 1
|
||||
}
|
||||
|
||||
.faceListRecoResultColumeIPAddr {
|
||||
text-align: center;
|
||||
flex: 2
|
||||
text-align: center;
|
||||
flex: 2
|
||||
}
|
||||
|
||||
.faceListRecoResultColumeDate {
|
||||
flex: 2
|
||||
flex: 2
|
||||
}
|
||||
|
||||
.faceListRecoResultColumeTime {
|
||||
flex: 1
|
||||
flex: 1
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -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="'http://127.0.0.1:9300/'+item.faceAddress" class="face_img" alt="">/>
|
||||
<img :src="'http://192.168.0.56:18093/'+item.faceAddress" class="face_img" alt="">/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
<div class="bottom-right-content">
|
||||
<img
|
||||
v-if="faceUrl"
|
||||
:src="'http://127.0.0.1:9300/'+faceUrl"
|
||||
:src="'http://192.168.0.56:18093/'+faceUrl"
|
||||
class="avatar"
|
||||
alt="Avatar"
|
||||
/>
|
||||
|
|
@ -85,7 +85,6 @@
|
|||
import addFace from "@/views/updateFace/addFace.vue";
|
||||
import {recognition} from '@/api/updateFace/updateFace'
|
||||
import faceListShowPic from "@/views/updateFace/faceListShowPic.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
addFace
|
||||
|
|
@ -101,9 +100,10 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
showModal(val) {
|
||||
/* if (!val) {
|
||||
console.log(val)
|
||||
if (!val) {
|
||||
faceListShowPic.methods.getList();
|
||||
}*/
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -126,6 +126,7 @@ export default {
|
|||
this.showModal = true
|
||||
},
|
||||
handleVisibleChange(newVal) {
|
||||
console.log(newVal);
|
||||
this.showModal = newVal;
|
||||
},
|
||||
selectFile() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue