|
|
|
@ -21,9 +21,6 @@ |
|
|
|
> |
|
|
|
<template slot-scope="{ data }"> |
|
|
|
<span class="tree-text">{{ data.deptName }}</span> |
|
|
|
<!-- <el-tooltip :content="data.deptName" placement="left"> |
|
|
|
<span class="tree-text">{{ data.deptName }}</span> |
|
|
|
</el-tooltip> --> |
|
|
|
</template> |
|
|
|
</el-tree> |
|
|
|
</el-scrollbar> |
|
|
|
@ -60,6 +57,10 @@ |
|
|
|
<i class="iconfont icon-zidonggengxin" /> |
|
|
|
同步 |
|
|
|
</el-button> |
|
|
|
<el-button :loading="syncFaceLoading" size="mini" style="background-color: #0348f3; color: #fff;" @click="toSyncFace()"> |
|
|
|
<i class="iconfont icon-yonghuguanli" /> |
|
|
|
自动人脸绑定 |
|
|
|
</el-button> |
|
|
|
</template> |
|
|
|
</crudOperation> |
|
|
|
</div> |
|
|
|
@ -113,7 +114,7 @@ |
|
|
|
</el-radio-group> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="状态" prop="platformStatus"> |
|
|
|
<!-- :disabled="form.id === user.id" --> |
|
|
|
<!-- :disabled="(crud.status.edit === 1 && form.addtype === 1) || form.id === user.id" --> |
|
|
|
<el-radio-group v-model="form.platformStatus" :disabled="crud.status.edit === 1 && form.addtype === 1"> |
|
|
|
<el-radio :label="1">激活</el-radio> |
|
|
|
<el-radio :label="2">禁用</el-radio> |
|
|
|
@ -126,17 +127,19 @@ |
|
|
|
</el-form-item> |
|
|
|
</el-form> |
|
|
|
<div class="right-user-img"> |
|
|
|
<!-- <img src="http://172.17.162.10:15000/api/minio/getImg?bucket=4&fileName=b89ea010-56fd-492c-a6d7-f4cb317116cb" alt="人员照片"> --> |
|
|
|
<img :src="imageUrl || require('@/assets/images/user.jpg')" alt="人员照片"> |
|
|
|
<div style="display: flex; flex-direction: column; align-items: center; "> |
|
|
|
<!-- 还需判断是否绑定过 --> |
|
|
|
<!-- <el-button v-if="crud.status.add !== 1" size="small" type="primary" style="background-color: #ed4a41; border-color: #ed4a41; color: #fff;"><i class="iconfont icon-jiebang" />清除绑定</el-button> |
|
|
|
<el-button size="small" type="primary" :loading="autoGetLoading" style="margin: 10px 0 0 0 !important;" @click="autoGetFaceUsers"><i class="iconfont icon-zidonggengxin" style="font-size: 14px !important;" />自动获取</el-button> --> |
|
|
|
<div style="display: flex; flex-direction: column; align-items: center; "> |
|
|
|
<el-button v-if="!hasBindFaceDb" size="small" type="primary" :loading="autoGetLoading" style="margin: 10px 0 !important;" @click="autoGetFaceUsers"> |
|
|
|
<i class="iconfont icon-zidonggengxin" style="font-size: 14px !important;" /> |
|
|
|
{{ crud.status.edit === 1 && form.facetBarcode !== null ? '重新获取' : '手动获取' }} |
|
|
|
</el-button> |
|
|
|
<!-- 新增清除按钮 --> |
|
|
|
<el-button v-if="form.facetBarcode" size="small" style="margin: 0 !important; background-color: rgb(246, 81, 99); border-color: rgb(246, 81, 99); color: rgb(255, 255, 255);" @click="clearFaceInfo"> |
|
|
|
<i class="iconfont icon-shanchu" style="font-size:14px" /> |
|
|
|
{{ hasBindFaceDb ? '解绑人脸' : '清除人脸' }} |
|
|
|
</el-button> |
|
|
|
</div> |
|
|
|
<!-- <div class="upload-btn" style="margin: 0 0 10px 0;"> |
|
|
|
<input id="upFile" type="file" name="upFile" accept="image/*" @change="changeFile($event)"> |
|
|
|
<el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />选择上传照片</el-button> |
|
|
|
</div> --> |
|
|
|
<!-- <el-button type="primary" @click="showCamera"><i class="iconfont icon-yulan" />摄像头拍摄</el-button> --> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div slot="footer" class="dialog-footer"> |
|
|
|
@ -146,24 +149,41 @@ |
|
|
|
</div> |
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
<!-- 人脸选择弹窗 --> |
|
|
|
<el-dialog |
|
|
|
:visible.sync="faceUserdialogVisible" |
|
|
|
title="人脸用户列表" |
|
|
|
width="500px" |
|
|
|
title="选择人脸用户" |
|
|
|
width="776px" |
|
|
|
class="face-select-dialog" |
|
|
|
append-to-body |
|
|
|
:close-on-click-modal="false" |
|
|
|
:modal-append-to-body="false" |
|
|
|
:visible.sync="faceSelectDialogVisible" |
|
|
|
> |
|
|
|
<el-table ref="faceUserTable" :data="faceUserTable" style="width: 100%" height="300px" max-height="300px" @selection-change="handleFaceUserSelectionChange"> |
|
|
|
<el-table-column type="selection" align="center" width="55" /> |
|
|
|
<el-table-column prop="lastname" label="账号" /> |
|
|
|
<el-table-column prop="lastname" label="用户名" /> |
|
|
|
<el-table-column prop="sex" label="性别" width="60" /> |
|
|
|
<el-table-column prop="departmentname" label="所属部门" /> |
|
|
|
</el-table> |
|
|
|
<div v-if="showGuessTip" class="guess-tip"> |
|
|
|
未查询到匹配人脸用户,猜测你是想从下面列表选择 |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="face-card-wrap"> |
|
|
|
<div |
|
|
|
v-for="item in autoFaceUserOptions" |
|
|
|
:key="item.guid" |
|
|
|
class="face-card-item" |
|
|
|
:class="{active: tempSelectFace?.guid === item.guid}" |
|
|
|
@click="tempSelectFace = item" |
|
|
|
> |
|
|
|
<img |
|
|
|
:src="baseApi + '/api/minio/getImg?bucket=2&fileName=' + item.guid" |
|
|
|
alt="人脸照片" |
|
|
|
class="face-img" |
|
|
|
> |
|
|
|
<div class="face-info"> |
|
|
|
<div class="face-name">{{ item.name }}</div> |
|
|
|
<div class="face-barcode">{{ item.barcode }}</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div slot="footer" class="dialog-footer"> |
|
|
|
<el-button @click="faceUserdialogVisible = false">取消</el-button> |
|
|
|
<el-button type="primary" @click="confirmFaceUserSelection">确定</el-button> |
|
|
|
<el-button @click="faceSelectDialogVisible = false">取消</el-button> |
|
|
|
<el-button type="primary" @click="confirmSelectFace">确定</el-button> |
|
|
|
</div> |
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
@ -182,8 +202,7 @@ |
|
|
|
</el-dialog> |
|
|
|
<!--表格渲染--> |
|
|
|
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" height="calc(100vh - 330px)" @row-click="clickRowHandler" @selection-change="crud.selectionChangeHandler"> |
|
|
|
<!-- :selectable="checkboxT" --> |
|
|
|
<el-table-column type="selection" align="center" width="55" /> |
|
|
|
<el-table-column type="selection" :selectable="checkboxT" align="center" width="55" /> |
|
|
|
<el-table-column prop="loginid" label="账号" /> |
|
|
|
<el-table-column prop="lastname" label="用户名" /> |
|
|
|
<el-table-column prop="sex" label="性别" width="60" /> |
|
|
|
@ -194,15 +213,15 @@ |
|
|
|
<el-tag v-if="scope.row.addtype === 1" type="success">同步用户</el-tag> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column prop="isFace" label="人脸绑定"> |
|
|
|
<el-table-column prop="facetBarcode" label="人脸绑定"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<el-tag v-if="scope.row.isFace === 1" type="success">已绑定</el-tag> |
|
|
|
<el-tag v-if="scope.row.isFace === 0" type="info">未绑定</el-tag> |
|
|
|
<el-tag v-if="scope.row.facetBarcode !== null" type="success">已绑定</el-tag> |
|
|
|
<el-tag v-else type="info">未绑定</el-tag> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column prop="platformStatus" label="状态" align="center" width="60"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<!-- :disabled="user.id === scope.row.userId" --> |
|
|
|
<!-- :disabled="user.id === scope.row.id" --> |
|
|
|
<el-switch v-if="scope.row.addtype===2" v-model="scope.row.platformStatus" active-color="#409EFF" inactive-color="#F56C6C" :active-value="1" :inactive-value="2" @change="changeEnabled(scope.row, scope.row.platformStatus)" /> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
@ -223,23 +242,18 @@ |
|
|
|
|
|
|
|
<script> |
|
|
|
import { getToken } from '@/utils/auth' |
|
|
|
import crudUser, { resetpassword, FetchSyncUser } from '@/api/system/user' |
|
|
|
// FetchSonDepts , getDepts, |
|
|
|
import crudUser, { resetpassword, FetchSyncUser, FetchSyncUserFace, FetchUnbindUserFace, FetchFaceTByNameAndFondsNo } from '@/api/system/user' |
|
|
|
import { getInitDeptTree } from '@/api/system/dept' |
|
|
|
import { getAll } from '@/api/system/role' |
|
|
|
import CRUD, { presenter, header, form, crud } from '@crud/crud' |
|
|
|
import crudOperation from '@crud/CRUD.operation' |
|
|
|
import pagination from '@crud/Pagination' |
|
|
|
// import Treeselect from '@riophae/vue-treeselect' |
|
|
|
import { mapGetters } from 'vuex' |
|
|
|
import '@riophae/vue-treeselect/dist/vue-treeselect.css' |
|
|
|
// import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' |
|
|
|
// import Vue from 'vue' |
|
|
|
import { exportFile } from '@/utils/index' |
|
|
|
import qs from 'qs' |
|
|
|
let userRoles = [] |
|
|
|
// dept: { id: null }, isAdmin: false, fonds: { id: null }, |
|
|
|
const defaultForm = { id: null, lastname: null, loginid: null, sex: '男', email: null, platformStatus: 1, roleIds: [], departmentid: null, mobile: null } |
|
|
|
const defaultForm = { id: null, lastname: null, loginid: null, sex: '男', email: null, platformStatus: 1, roleIds: [], departmentid: null, mobile: null, facetBarcode: null, facePhoto: null } |
|
|
|
export default { |
|
|
|
name: 'User', |
|
|
|
components: { crudOperation, pagination }, |
|
|
|
@ -282,10 +296,6 @@ export default { |
|
|
|
defaultProps: { children: 'children', label: 'deptName' }, |
|
|
|
levelNumber: 0, |
|
|
|
permission: { add: [], edit: [], del: [] }, |
|
|
|
enabledTypeOptions: [ |
|
|
|
{ key: '1', display_name: '激活' }, |
|
|
|
{ key: '0', display_name: '锁定' } |
|
|
|
], |
|
|
|
userTypeOptions: [ |
|
|
|
{ value: 1, label: '同步用户' }, |
|
|
|
{ value: 2, label: '自建用户' } |
|
|
|
@ -311,14 +321,18 @@ export default { |
|
|
|
{ trigger: 'blur', validator: validateRole } |
|
|
|
] |
|
|
|
}, |
|
|
|
imageUrl: null, |
|
|
|
faceUserdialogVisible: false, |
|
|
|
faceUserTable: [], |
|
|
|
autoGetLoading: false, |
|
|
|
selectedFaceUser: null, |
|
|
|
deptGroupOptions: [], |
|
|
|
syncLoading: false, |
|
|
|
selectedDeptInfo: null |
|
|
|
selectedDeptInfo: null, |
|
|
|
autoFaceUserValue: null, |
|
|
|
autoFaceUserOptions: [], |
|
|
|
syncFaceLoading: false, |
|
|
|
hasBindFaceDb: false, // 标记数据库是否存在人脸绑定 |
|
|
|
imageUrl: null, |
|
|
|
showGuessTip: false, // 是否展示猜测提示 |
|
|
|
faceSelectDialogVisible: false, // 人脸弹窗显示 |
|
|
|
tempSelectFace: null, // 弹窗内临时选中对象 |
|
|
|
autoGetLoading: false |
|
|
|
} |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
@ -344,7 +358,7 @@ export default { |
|
|
|
this.syncLoading = true |
|
|
|
FetchSyncUser().then((res) => { |
|
|
|
console.log('res', res) |
|
|
|
if (res) { |
|
|
|
if (res.code !== null) { |
|
|
|
this.$message({ message: '同步用户数据成功', type: 'success', offset: 8 }) |
|
|
|
this.crud.toQuery() |
|
|
|
} else { |
|
|
|
@ -357,6 +371,23 @@ export default { |
|
|
|
this.syncLoading = false |
|
|
|
}) |
|
|
|
}, |
|
|
|
toSyncFace() { |
|
|
|
this.syncFaceLoading = true |
|
|
|
FetchSyncUserFace().then((res) => { |
|
|
|
console.log('res', res) |
|
|
|
if (res) { |
|
|
|
this.$message({ message: res.message, type: 'success', offset: 8 }) |
|
|
|
this.crud.toQuery() |
|
|
|
} else { |
|
|
|
this.$message({ message: '自动绑定人脸数据失败', type: 'error', offset: 8 }) |
|
|
|
} |
|
|
|
this.syncFaceLoading = false |
|
|
|
}).catch(err => { |
|
|
|
console.log('自动绑定人脸数据失败', err) |
|
|
|
this.$message({ message: '自动绑定人脸数据失败', type: 'error', offset: 8 }) |
|
|
|
this.syncFaceLoading = false |
|
|
|
}) |
|
|
|
}, |
|
|
|
// 根据 internalId 查找完整部门对象(编辑专用) |
|
|
|
getDeptByInternalId(internalId) { |
|
|
|
if (!internalId) return null |
|
|
|
@ -368,6 +399,7 @@ export default { |
|
|
|
}, |
|
|
|
// 选择部门时,获取完整信息(含编码、名称) |
|
|
|
handleDeptChange(val) { |
|
|
|
console.log('val', val) |
|
|
|
this.selectedDeptInfo = val |
|
|
|
this.form.departmentid = val ? val.deptsId : null |
|
|
|
}, |
|
|
|
@ -413,17 +445,26 @@ export default { |
|
|
|
delete this.crud.params.size |
|
|
|
} |
|
|
|
}, |
|
|
|
[CRUD.HOOK.beforeAddCancel]() { |
|
|
|
this.autoFaceUserOptions = [] |
|
|
|
this.imageUrl = null |
|
|
|
this.tempSelectFace = null |
|
|
|
this.faceSelectDialogVisible = false |
|
|
|
this.showGuessTip = false |
|
|
|
}, |
|
|
|
[CRUD.HOOK.beforeEditCancel]() { |
|
|
|
this.autoFaceUserOptions = [] |
|
|
|
this.imageUrl = null |
|
|
|
this.tempSelectFace = null |
|
|
|
this.faceSelectDialogVisible = false |
|
|
|
this.showGuessTip = false |
|
|
|
}, |
|
|
|
// 新增与编辑前做的操作 |
|
|
|
[CRUD.HOOK.afterToCU](crud, form) { |
|
|
|
this.getRoles() |
|
|
|
// 编辑回显部门(自动显示名称) |
|
|
|
if (form.departmentid) { |
|
|
|
this.selectedDeptInfo = this.getDeptByInternalId(form.departmentid) |
|
|
|
// if (form.internalId) { |
|
|
|
// this.selectedDeptInfo = this.getDeptByInternalId(form.departmentid) |
|
|
|
// } else { |
|
|
|
// this.selectedDeptInfo = this.findDeptObjById(form.departmentid) |
|
|
|
// } |
|
|
|
} else { |
|
|
|
const deptObj = this.findDeptObjById(this.query.deptId) |
|
|
|
this.selectedDeptInfo = deptObj |
|
|
|
@ -433,39 +474,10 @@ export default { |
|
|
|
// 新增前将多选的值设置为空 |
|
|
|
[CRUD.HOOK.beforeToAdd](crud, form) { |
|
|
|
// 清空角色、部门等额外数据 |
|
|
|
this.hasBindFaceDb = false |
|
|
|
this.roleDatas = [] |
|
|
|
this.selectedDeptInfo = null |
|
|
|
}, |
|
|
|
// 初始化编辑时候的角色与岗位 |
|
|
|
// [CRUD.HOOK.beforeToEdit](crud, form) { |
|
|
|
// form.roleIds = [] |
|
|
|
// this.leftDeptsId = crud.form.departmentid |
|
|
|
// if (form.roleIds.includes(',')) { |
|
|
|
// const arr = form.roleIds.split(',') |
|
|
|
// this.roles.map((role) => { |
|
|
|
// arr.forEach(item => { |
|
|
|
// if (item === String(role.name)) { |
|
|
|
// return form.roleIds.push(role) |
|
|
|
// } |
|
|
|
// }) |
|
|
|
// }) |
|
|
|
// } else { |
|
|
|
// this.roles.map((role) => { |
|
|
|
// if (form.roleIds === String(role.name)) { |
|
|
|
// return form.roles.push(role) |
|
|
|
// } |
|
|
|
// }) |
|
|
|
// } |
|
|
|
// this.roleDatas = [] |
|
|
|
// userRoles = [] |
|
|
|
// const _this = this |
|
|
|
// form.roleIds.forEach(function(role, index) { |
|
|
|
// _this.roleDatas.push(role.id) |
|
|
|
// const rol = { id: role.id } |
|
|
|
// userRoles.push(rol) |
|
|
|
// }) |
|
|
|
// crud.form.id = crud.form.userId |
|
|
|
// }, |
|
|
|
[CRUD.HOOK.beforeToEdit](crud, form) { |
|
|
|
// 先清空,避免上次编辑数据残留 |
|
|
|
this.roleDatas = [] |
|
|
|
@ -473,6 +485,15 @@ export default { |
|
|
|
|
|
|
|
if (form.id) { |
|
|
|
const params = { userId: form.id } |
|
|
|
|
|
|
|
this.hasBindFaceDb = !!form.facePhoto && !!form.facetBarcode |
|
|
|
if (form.facePhoto) { |
|
|
|
const linkSrc = window.g.ApiUrl |
|
|
|
this.imageUrl = linkSrc + '/api/minio/getImg?bucket=4&fileName=' + form.facePhoto + '.bmp' |
|
|
|
} else { |
|
|
|
this.imageUrl = null |
|
|
|
} |
|
|
|
|
|
|
|
crudUser.FetchUserDetailsById(params).then(res => { |
|
|
|
console.log('获取用户详情成功', res) |
|
|
|
|
|
|
|
@ -523,6 +544,10 @@ export default { |
|
|
|
return true |
|
|
|
}, |
|
|
|
clickRowHandler(row) { |
|
|
|
// 当前点击行是自身,禁止选中 |
|
|
|
// if (row.id === this.user.id) { |
|
|
|
// return |
|
|
|
// } |
|
|
|
this.$refs.table.clearSelection() |
|
|
|
this.$refs.table.toggleRowSelection(row) |
|
|
|
}, |
|
|
|
@ -557,18 +582,7 @@ export default { |
|
|
|
}, |
|
|
|
changeRole(value) { |
|
|
|
userRoles = [...value] |
|
|
|
// value.forEach(function(data, index) { |
|
|
|
// const role = { id: data } |
|
|
|
// userRoles.push(role) |
|
|
|
// }) |
|
|
|
}, |
|
|
|
// deleteTag(value) { |
|
|
|
// userRoles.forEach(function(data, index) { |
|
|
|
// if (data.id === value) { |
|
|
|
// userRoles.splice(index, value) |
|
|
|
// } |
|
|
|
// }) |
|
|
|
// }, |
|
|
|
}, |
|
|
|
deleteTag(value) { |
|
|
|
const index = userRoles.findIndex(item => item === value) |
|
|
|
if (index > -1) { |
|
|
|
@ -633,7 +647,6 @@ export default { |
|
|
|
} |
|
|
|
groupMap[key].children.push(item) |
|
|
|
}) |
|
|
|
|
|
|
|
// 构建下拉分组数据 |
|
|
|
Object.values(groupMap).forEach(group => { |
|
|
|
groupSelectOptions.push({ |
|
|
|
@ -642,7 +655,9 @@ export default { |
|
|
|
deptsId: child.deptsId, |
|
|
|
deptName: child.deptName, |
|
|
|
internalId: child.internalId, |
|
|
|
departmentCode: child.departmentCode || null |
|
|
|
departmentCode: child.departmentCode || null, |
|
|
|
fondsNo: child.fondsNo, |
|
|
|
group: { label: group.deptName } |
|
|
|
})) |
|
|
|
}) |
|
|
|
}) |
|
|
|
@ -655,7 +670,9 @@ export default { |
|
|
|
deptsId: item.deptsId, |
|
|
|
deptName: item.deptName, |
|
|
|
internalId: item.internalId, |
|
|
|
departmentCode: item.departmentCode || null |
|
|
|
departmentCode: item.departmentCode || null, |
|
|
|
fondsNo: item.fondsNo, |
|
|
|
group: { label: '其他部门' } |
|
|
|
})) |
|
|
|
}) |
|
|
|
} |
|
|
|
@ -679,83 +696,12 @@ export default { |
|
|
|
this.handleNodeClick(rootNode) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
// console.log('this.fondsDatas', this.fondsDatas) |
|
|
|
// this.$nextTick(() => { |
|
|
|
// if (root.children.length) { |
|
|
|
// let first = null |
|
|
|
// if (root.children[0].children) { |
|
|
|
// first = root.children[0].children[0] |
|
|
|
// } else { |
|
|
|
// first = root.children[0] |
|
|
|
// } |
|
|
|
// if (first) { |
|
|
|
// this.$refs.tree.setCurrentKey(first.id) |
|
|
|
// this.handleNodeClick(first) |
|
|
|
// } |
|
|
|
// } |
|
|
|
// }) |
|
|
|
}) |
|
|
|
}, |
|
|
|
filterNode(value, data) { |
|
|
|
if (!value) return true |
|
|
|
return data.deptName?.includes(value) |
|
|
|
}, |
|
|
|
// changeFondsValue(value) { |
|
|
|
// this.depts = [] |
|
|
|
// console.log(this.lastValue) |
|
|
|
// if (this.lastValue) { |
|
|
|
// if (value !== this.lastValue) { |
|
|
|
// this.form.dept.id = null |
|
|
|
// } |
|
|
|
// } |
|
|
|
// var obj = {} |
|
|
|
// obj = this.fondsOptions.find(function(item) { |
|
|
|
// return item.id === value |
|
|
|
// }) |
|
|
|
// const params = { |
|
|
|
// 'fondsId': obj.id, |
|
|
|
// 'fondsName': obj.fondsName, |
|
|
|
// 'status': 1 |
|
|
|
// } |
|
|
|
// this.getDepts(params) |
|
|
|
// }, |
|
|
|
// getDepts(params) { |
|
|
|
// getDepts(params).then(res => { |
|
|
|
// this.depts = res.content.map(function(obj) { |
|
|
|
// if (obj.sonNum !== 0) { |
|
|
|
// obj.hasChildren = true |
|
|
|
// } else { |
|
|
|
// obj.hasChildren = false |
|
|
|
// } |
|
|
|
// if (obj.hasChildren) { |
|
|
|
// obj.children = null |
|
|
|
// } |
|
|
|
// return obj |
|
|
|
// }) |
|
|
|
// }) |
|
|
|
// }, |
|
|
|
// 获取弹窗内部门数据 |
|
|
|
// loadDepts({ action, parentNode, callback }) { |
|
|
|
// if (action === LOAD_CHILDREN_OPTIONS) { |
|
|
|
// FetchSonDepts({ deptsId: parentNode.deptsId }).then(res => { |
|
|
|
// parentNode.children = res.map(function(obj) { |
|
|
|
// if (obj.sonNum !== 0) { |
|
|
|
// obj.hasChildren = true |
|
|
|
// } else { |
|
|
|
// obj.hasChildren = false |
|
|
|
// } |
|
|
|
// if (obj.hasChildren) { |
|
|
|
// obj.children = null |
|
|
|
// } |
|
|
|
// return obj |
|
|
|
// }) |
|
|
|
// setTimeout(() => { |
|
|
|
// callback() |
|
|
|
// }, 100) |
|
|
|
// }) |
|
|
|
// } |
|
|
|
// }, |
|
|
|
// 删除用户 |
|
|
|
toDelete(datas) { |
|
|
|
this.deleteData = datas |
|
|
|
@ -829,67 +775,123 @@ export default { |
|
|
|
}) |
|
|
|
}, |
|
|
|
checkboxT(row, rowIndex) { |
|
|
|
return row.userId !== this.user.id |
|
|
|
}, |
|
|
|
// fondsNormalizer(node) { |
|
|
|
// if (node.children && !node.children.length) { |
|
|
|
// delete node.children |
|
|
|
// } |
|
|
|
// return { |
|
|
|
// id: node.id, |
|
|
|
// label: node.fondsName, |
|
|
|
// children: node.children |
|
|
|
// } |
|
|
|
// }, |
|
|
|
// normalizer(node) { |
|
|
|
// if (node.children && !node.children.length) { |
|
|
|
// delete node.children |
|
|
|
// } |
|
|
|
// return { |
|
|
|
// id: node.deptsId, |
|
|
|
// label: node.deptsName, |
|
|
|
// children: node.children |
|
|
|
// } |
|
|
|
// }, |
|
|
|
// 自动获取人脸用户 |
|
|
|
autoGetFaceUsers() { |
|
|
|
return row.id !== this.user.id |
|
|
|
}, |
|
|
|
async autoGetFaceUsers() { |
|
|
|
this.autoFaceUserOptions = [] |
|
|
|
this.tempSelectFace = null |
|
|
|
this.showGuessTip = false |
|
|
|
// 选部门传市州 |
|
|
|
if (!this.selectedDeptInfo) { |
|
|
|
this.$message({ message: '请先选择所属部门', type: 'warning', offset: 8 }) |
|
|
|
return |
|
|
|
} |
|
|
|
this.autoGetLoading = true |
|
|
|
// 模拟后端接口调用 |
|
|
|
setTimeout(() => { |
|
|
|
// 模拟数据 |
|
|
|
this.faceUserTable = [ |
|
|
|
{ userId: 1, loginid: 'user1', lastname: '用户1', sex: '男', deptsName: '技术部' }, |
|
|
|
{ userId: 2, loginid: 'user2', lastname: '用户2', sex: '女', deptsName: '市场部' }, |
|
|
|
{ userId: 3, loginid: 'user3', lastname: '用户3', sex: '男', deptsName: '财务部' } |
|
|
|
] |
|
|
|
|
|
|
|
try { |
|
|
|
// 第一次请求:携带用户名查询 |
|
|
|
const paramsFirst = { |
|
|
|
fondsNo: this.selectedDeptInfo.fondsNo, |
|
|
|
name: this.form.lastname || '' |
|
|
|
} |
|
|
|
console.log('第一次查询人脸参数(带名称):', paramsFirst) |
|
|
|
let resList = await FetchFaceTByNameAndFondsNo(paramsFirst) |
|
|
|
// [ |
|
|
|
// { |
|
|
|
// 'barcode': 'S00101_1', |
|
|
|
// 'guid': 'd98f0098-10b7-4132-a177-f1c8c508e44a', |
|
|
|
// 'name': '周磊', |
|
|
|
// 'opTime': '2026-05-19T06:29:03.260+00:00', |
|
|
|
// 'groupindex': 0, |
|
|
|
// 'isupdate': 1, |
|
|
|
// 'libcode': 'S00101', |
|
|
|
// 'score': 0, |
|
|
|
// 'remarks': null |
|
|
|
// } |
|
|
|
// ] |
|
|
|
|
|
|
|
// 第一次查询没有数据 && 当前存在用户名 → 二次查询,清空name |
|
|
|
if ((!resList || resList.length === 0) && this.form.lastname) { |
|
|
|
const paramsSecond = { |
|
|
|
fondsNo: this.selectedDeptInfo.fondsNo, |
|
|
|
name: '' |
|
|
|
} |
|
|
|
console.log('未匹配到数据,执行第二次查询(清空用户名)', paramsSecond) |
|
|
|
resList = await FetchFaceTByNameAndFondsNo(paramsSecond) |
|
|
|
// 开启顶部提示 |
|
|
|
this.showGuessTip = true |
|
|
|
} |
|
|
|
this.autoGetLoading = false |
|
|
|
if (!resList || resList.length === 0) { |
|
|
|
this.$message({ message: '未查询到该市州下的人脸数据', type: 'info', offset: 8 }) |
|
|
|
return |
|
|
|
} |
|
|
|
this.autoFaceUserOptions = resList |
|
|
|
// 打开弹窗 |
|
|
|
this.faceSelectDialogVisible = true |
|
|
|
} catch (err) { |
|
|
|
console.error('获取人脸异常:', err) |
|
|
|
this.autoGetLoading = false |
|
|
|
this.faceUserdialogVisible = true |
|
|
|
}, 1500) |
|
|
|
}, |
|
|
|
// 处理人脸用户选择 |
|
|
|
handleFaceUserSelectionChange(selection) { |
|
|
|
// 确保只单选 |
|
|
|
if (selection.length > 1) { |
|
|
|
this.$refs.faceUserTable.clearSelection() |
|
|
|
this.$refs.faceUserTable.toggleRowSelection(selection[selection.length - 1]) |
|
|
|
this.selectedFaceUser = selection[selection.length - 1] |
|
|
|
} else if (selection.length === 1) { |
|
|
|
this.selectedFaceUser = selection[0] |
|
|
|
this.$message({ message: '查询人脸失败', type: 'error', offset: 8 }) |
|
|
|
} |
|
|
|
}, |
|
|
|
// 确认弹窗选中人脸 |
|
|
|
confirmSelectFace() { |
|
|
|
if (!this.tempSelectFace) { |
|
|
|
this.$message({ message: '请选择一条人脸信息', type: 'warning', offset: 8 }) |
|
|
|
return |
|
|
|
} |
|
|
|
// 回填到表单与人像预览 |
|
|
|
this.fillUserData(this.tempSelectFace) |
|
|
|
this.faceSelectDialogVisible = false |
|
|
|
}, |
|
|
|
|
|
|
|
// 下拉选中用户回调 |
|
|
|
handleSelectFaceUser(userInfo) { |
|
|
|
if (!userInfo) return |
|
|
|
this.fillUserData(userInfo) |
|
|
|
}, |
|
|
|
// 统一回填表单和头像 |
|
|
|
fillUserData(userInfo) { |
|
|
|
this.form.facetBarcode = userInfo.barcode |
|
|
|
this.form.facePhoto = userInfo.guid |
|
|
|
|
|
|
|
if (!this.form.lastname) { |
|
|
|
this.form.lastname = userInfo.name |
|
|
|
} |
|
|
|
// const linkSrc = process.env.NODE_ENV === 'production' ? window.g.ApiUrl : process.env.VUE_APP_BASE_API |
|
|
|
const linkSrc = window.g.ApiUrl |
|
|
|
if (userInfo.guid) { |
|
|
|
this.imageUrl = linkSrc + '/api/minio/getImg?bucket=4&fileName=' + userInfo.guid + '.bmp' |
|
|
|
// this.imageUrl = 'http://172.17.162.10:15000/api/minio/getImg?bucket=4&fileName=b89ea010-56fd-492c-a6d7-f4cb317116cb.bmp' |
|
|
|
} else { |
|
|
|
this.selectedFaceUser = null |
|
|
|
this.imageUrl = null |
|
|
|
} |
|
|
|
}, |
|
|
|
// 确认选择人脸用户 |
|
|
|
confirmFaceUserSelection() { |
|
|
|
if (this.selectedFaceUser) { |
|
|
|
// 将选中的数据传递给form |
|
|
|
this.form.lastname = this.selectedFaceUser.lastname |
|
|
|
this.form.nickName = this.selectedFaceUser.nickName |
|
|
|
this.form.sex = this.selectedFaceUser.sex |
|
|
|
// 这里可以根据实际需要处理部门信息 |
|
|
|
this.faceUserdialogVisible = false |
|
|
|
// 清除已选择人脸信息 |
|
|
|
clearFaceInfo() { |
|
|
|
// 只有数据库存在绑定记录,才调用后端解绑接口 |
|
|
|
if (this.hasBindFaceDb) { |
|
|
|
FetchUnbindUserFace({ |
|
|
|
id: this.form.id |
|
|
|
}).then(res => { |
|
|
|
console.log('res', res) |
|
|
|
if (res === '解绑成功') { |
|
|
|
this.$message({ message: res, type: 'success', offset: 8 }) |
|
|
|
this.form.facetBarcode = null |
|
|
|
this.form.facePhoto = null |
|
|
|
this.imageUrl = null |
|
|
|
this.hasBindFaceDb = false |
|
|
|
this.crud.refresh() |
|
|
|
} else { |
|
|
|
this.$message({ message: res.msg || '解绑失败', type: 'error', offset: 8 }) |
|
|
|
} |
|
|
|
}) |
|
|
|
} else { |
|
|
|
this.$message({ message: '请选择一个用户', type: 'warning', offset: 8 }) |
|
|
|
// 只是前端临时选择,数据库没有绑定,仅前端清空,不请求接口 |
|
|
|
this.form.facetBarcode = null |
|
|
|
this.form.facePhoto = null |
|
|
|
this.imageUrl = null |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -937,7 +939,7 @@ export default { |
|
|
|
display: block; |
|
|
|
width: 150px; |
|
|
|
height: 200px; |
|
|
|
margin: 0 0 20px 0; |
|
|
|
// margin: 0 0 20px 0; |
|
|
|
} |
|
|
|
} |
|
|
|
.upload-btn{ |
|
|
|
@ -959,6 +961,7 @@ export default { |
|
|
|
} |
|
|
|
.el-table{ |
|
|
|
::v-deep .el-tag{ |
|
|
|
margin: 0 !important; |
|
|
|
&.el-tag--small{ |
|
|
|
color: #0348f3 !important; |
|
|
|
background-color: #eef5fe !important; |
|
|
|
@ -976,4 +979,66 @@ export default { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
.face-select-dialog{ |
|
|
|
::v-deep .el-dialog{ |
|
|
|
.el-dialog__body{ |
|
|
|
padding: 10px 0 0 0; |
|
|
|
} |
|
|
|
.el-dialog__footer{ |
|
|
|
padding: 10px 0 20px 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
.face-card-wrap { |
|
|
|
max-height: 425px; |
|
|
|
overflow-y: auto; |
|
|
|
display: flex; |
|
|
|
flex-wrap: wrap; |
|
|
|
gap: 16px; |
|
|
|
padding: 10px 0; |
|
|
|
} |
|
|
|
.face-card-item { |
|
|
|
width: 130px; |
|
|
|
border: 1px solid #e4e7ed; |
|
|
|
border-radius: 6px; |
|
|
|
padding: 10px; |
|
|
|
cursor: pointer; |
|
|
|
transition: 0.2s; |
|
|
|
&:hover { |
|
|
|
border-color: #409EFF; |
|
|
|
} |
|
|
|
&.active { |
|
|
|
border-color: #409EFF; |
|
|
|
background-color: #ecf5ff; |
|
|
|
} |
|
|
|
.face-img { |
|
|
|
display: block; |
|
|
|
width: 110px; |
|
|
|
height: 145px; |
|
|
|
object-fit: cover; |
|
|
|
border-radius: 4px; |
|
|
|
} |
|
|
|
.face-info { |
|
|
|
margin-top: 8px; |
|
|
|
text-align: center; |
|
|
|
} |
|
|
|
.face-name { |
|
|
|
font-size: 14px; |
|
|
|
color: #333; |
|
|
|
} |
|
|
|
.face-barcode { |
|
|
|
font-size: 12px; |
|
|
|
color: #909399; |
|
|
|
margin-top: 4px; |
|
|
|
word-break: break-all; |
|
|
|
} |
|
|
|
} |
|
|
|
.guess-tip{ |
|
|
|
padding: 8px 12px; |
|
|
|
background: #fff7e6; |
|
|
|
color: #fa8c16; |
|
|
|
border-radius: 4px; |
|
|
|
margin-bottom: 12px; |
|
|
|
font-size:14px; |
|
|
|
} |
|
|
|
</style> |