first commit

This commit is contained in:
zc
2025-06-05 09:55:41 +08:00
commit 935360c185
459 changed files with 61034 additions and 0 deletions

771
src/views/visitor/index.vue Normal file
View File

@@ -0,0 +1,771 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="来访人" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入来访人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="被访人" prop="userId">
<el-input
v-model="queryParams.userId"
placeholder="请输入被访人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="访问园区/企业" prop="deptId">
<el-input
v-model="queryParams.deptId"
placeholder="请输入访问部门"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<el-form-item label="预约时间" prop="startTime">
<el-date-picker clearable
v-model="queryParams.startTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择预约时间">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['visitor:visitor:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['visitor:visitor:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['visitor:visitor:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['visitor:visitor:export']"
>导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-menu"
size="mini"
@click="handleEwm"
v-hasPermi="['visitor:visitor:ewm']"
>二维码</el-button>
<el-image-viewer v-if="showViewer" :on-close="closeViewer" :url-list="[url]" />
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="visitorList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="来访人" align="center" prop="name" />
<el-table-column label="用户性别" align="center" prop="sex">
<template slot-scope="scope">
<template v-if="scope.row.sex != null">
<dict-tag :options="dict.type.sys_user_sex" :value="scope.row.sex"/>
</template>
<template v-else>保密</template>
</template>
</el-table-column>
<el-table-column label="人员头像" align="center" prop="avatar" >
<template v-slot="scope">
<el-image
style="width: 80px; height: 80px"
:src="scope.row.avatar"
:preview-src-list="[scope.row.avatar]" >
</el-image>
<!-- <div class="published-div" v-if="scope.row.faceGuid!=undefined">
<el-button type="success" icon="el-icon-check" size="mini" circle></el-button>
</div>
<div class="published-div" v-if="scope.row.faceGuid==undefined">
<el-button type="danger" icon="el-icon-close" size="mini" circle></el-button>
</div> -->
</template>
</el-table-column>
<el-table-column label="访问园区/企业" align="center" prop="deptId" >
<template slot-scope="scope" >
<span v-if="scope.row.branch!=null">{{scope.row.branch.name}}</span>
</template>
</el-table-column>
<el-table-column label="被访人" align="center" prop="userId" >
<template slot-scope="scope">
<span v-if="scope.row.people!=null">{{scope.row.people.name}}</span>
</template>
</el-table-column>
<el-table-column label="预约时间" align="center" prop="startTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.startTime) }}</span>
</template>
</el-table-column>
<el-table-column label="进入时间" align="center" prop="inTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.inTime) }}</span>
</template>
</el-table-column>
<el-table-column label="离开时间" align="center" prop="outTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.outTime) }}</span>
</template>
</el-table-column>
<el-table-column label="审核状态" align="center" prop="examine" width="180">
<template slot-scope="scope">
<template v-if="scope.row.examine.examine == null">未审核</template>
<template v-else>
<template v-if="scope.row.examine.examine == 0">通过</template>
<template v-else-if="scope.row.examine.examine == 1">驳回</template>
</template>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
:disabled="scope.row.examine.examine == 0"
@click="handleUpdate(scope.row)"
v-hasPermi="['visitor:visitor:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['visitor:visitor:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改访客信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="24" >
<el-form-item label="来访人头像" prop="avatar">
<div class="card_list" >
<image-upload v-model="form.avatar" :limit="1" :isShowTip="false" />
<div class="avater_box">
<div class="avater_l">
<!-- <el-popover
placement="top-start"
title="注册照片示例"
width="500"
trigger="hover">
<div class="txt">照片要求</div>
<el-image
:src="logo"
:preview-src-list="[logo]" >
</el-image>
<el-button slot="reference">照片示例图</el-button>
</el-popover> -->
<div class="txt">1确保照片是正脸且足够清晰同一个人最多3张注册照</div>
<div class="txt" >2照片格式支持JPG\JPEG\PNG</div>
<div class="txt">3小于2M</div>
<div class="txt">4面部区域像素不低于128x128</div>
<div class="txt">5人像大小占整张照片1/3以上</div>
</div>
<div class="avater_r">
<img :src="logo" />
</div>
</div>
</div>
</el-form-item>
</el-col>
<el-col :span="8" >
<el-form-item label="来访人" prop="name">
<el-input v-model="form.name" placeholder="请输入来访人" />
</el-form-item>
</el-col>
<el-col :span="8" >
<el-form-item label="联系电话" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系电话" />
</el-form-item>
</el-col>
<el-col :span="8" >
<el-form-item label="来访人性别" prop="sex">
<el-select v-model="form.sex" placeholder="请选择用户性别">
<el-option
v-for="dict in dict.type.sys_user_sex"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" >
<el-form-item label="身份证号码" prop="idcard">
<el-input v-model="form.idcard" placeholder="请输入身份证号码" />
</el-form-item>
</el-col>
<el-col :span="8" >
<el-form-item label="车牌号码" prop="carNo">
<el-input v-model="form.carNo" placeholder="请输入车牌号码" />
</el-form-item>
</el-col>
<!-- <el-col :span="8" >
<el-form-item label="访客类型" prop="flag">
<el-select v-model="form.flag" placeholder="请选择访客类型">
<el-option
v-for="dict in dict.type.vis_info_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col> -->
<el-col :span="8" >
<el-form-item label="园区/公司" prop="deptId">
<!-- <treeselect v-model="form.deptId" :options="branchOptions" :defaultExpandLevel="Infinity" :normalizer="normalizer" placeholder="选择拜访园区/公司" @select="departTreeSelected" /> -->
<el-select v-model="form.deptId" placeholder="请选择园区/公司">
<el-option
v-for="dict in dict.type.sys_company_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" >
<el-form-item label="被访人" prop="userName">
<!-- <el-select v-model="form.userId" placeholder="请输入被访人手机号搜索" filterable :filter-method="dataFilter">
<el-option
v-for="dict in peopleOptions"
:key="dict.id"
:label="dict.name"
:value="dict.id"
></el-option>
</el-select> -->
<el-input v-model="form.userName" placeholder="请输入被访人手机号搜索" @input="dataFilter" maxlength="11" />
</el-form-item>
</el-col>
<el-col :span="8" >
<el-form-item label="预约时间" prop="startTime">
<el-date-picker clearable
v-model="form.startTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择预约时间">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8" >
<el-form-item label="结束时间" prop="endTime">
<el-date-picker clearable
v-model="form.endTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择来访结束时间">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8" >
<el-form-item label="访客事由" prop="matter">
<!-- <el-input v-model="form.matter" placeholder="请输入来访事由" /> -->
<el-select v-model="form.matter" placeholder="请选择访客事由">
<el-option
v-for="dict in dict.type.vis_info_reason"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" >
<el-form-item label="携带物品" prop="res">
<el-input v-model="form.res" placeholder="请输入携带物品" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.id!=null" >
<el-form-item label="头像注册状态" prop="faceGuid" label-width="100px">
<el-switch v-if="form.faceGuid!=undefined" :value="true"
disabled>
</el-switch>
<el-switch v-if="form.faceGuid==undefined" :value="false"
disabled>
</el-switch>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.id!=null">
<el-form-item label="人员注册状态" prop="guid" label-width="100px">
<el-switch v-if="form.guid!=undefined" :value="true"
disabled>
</el-switch>
<el-switch v-if="form.guid==undefined" :value="false"
disabled>
</el-switch>
</el-form-item>
</el-col>
<el-col :span="24" >
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
<!--添加按钮-->
<!--
<el-button type="primary" style="float: left;" >随访人员信息</el-button>
-->
<el-tag effect="dark" style="float: left;">随访人员信息</el-tag>
<el-button type="success" style="float: right;" size="medium" @click="addRow(itemData.length)">添加</el-button>
<!--表格-->
<el-table :data="itemData" style="width: 100%" ref="tb" class="people_table">
<el-table-column fixed prop="date" label="人员头像">
<template slot-scope="scope">
<image-upload v-model="scope.row.avatar" style="width: 80px; height: 80px" :limit="1" :isShowTip="false" />
<!-- <div class="published-div" v-if="scope.row.faceGuid!=undefined">
<el-button type="success" icon="el-icon-check" size="mini" circle></el-button>
</div>
<div class="published-div" v-if="scope.row.faceGuid==undefined && scope.row.id !=undefined">
<el-button type="danger" icon="el-icon-close" size="mini" circle></el-button>
</div> -->
</template>
</el-table-column>
<el-table-column prop="name" label="姓名" align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.name" :label="scope.row.index"></el-input>
</template>
</el-table-column>
<el-table-column prop="phone" label="电话号码" align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.phone" :label="scope.row.index"></el-input>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" align="center">
<template slot-scope="scope">
<el-button @click.native.prevent="deleteRow(scope.$index, itemData)" type="text" size="small">移除</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import moment from 'moment';
import { listVisitor, getVisitor, delVisitor, addVisitor, updateVisitor,queryPeopleName } from "@/api/visitor/visitor";
import logoImg from '@/assets/images/exampleavater.png'
import {branchTreeSelect} from "@/api/system/sysBranch";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import {listSysPeople} from "@/api/system/sysPeople";
import urlImg from '@/assets/images/ewm.png';
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
export default {
name: "Visitor",
dicts: ['sys_user_sex','vis_info_type','vis_info_reason','sys_company_type'],
components: {Treeselect,ElImageViewer },
data() {
return {
subFlag:1,
showViewer: false, // 显示查看器
url:urlImg,
logo: logoImg,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 访客信息表格数据
visitorList: [],
// 部门树选项
branchOptions: [],
peopleOptions:[],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
name: null,
sex: null,
avatar: null,
userId: null,
deptId: null,
startTime: null,
},
queryParams1: {
branchId: undefined,
pageNum: 1,
pageSize: 99999
},
// 表单参数
form: {},
// 表单校验
rules: {
name: [
{ required: true, message: "来访人不能为空", trigger: "blur" }
],
phone: [
{ required: true, message: "来访人联系电话不能为空", trigger: "blur" },
{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,message: "请输入正确的手机号码",trigger: "blur"}
],
idcard: [
{ pattern: /^[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}[0-9Xx]$/,message: "请输入正确的身份证号码",trigger: "blur"}
],
startTime: [
{ required: true, message: "预约时间不能为空", trigger: "blur" }
],
endTime: [
{ required: true, message: "结束时间不能为空", trigger: "blur" }
],
userName: [
{ required: true, message: "被访人不能为空", trigger: "blur" }
],
matter: [
{ required: true, message: "访客事由不能为空", trigger: "blur" }
],
deptId: [
{ required: true, message: "园区/公司不能为空", trigger: "blur" }
],
},
//给一个默认行
itemData: []
};
},
created() {
this.getList();
this.getOptions();
},
methods: {
/** 查询访客信息列表 */
getList() {
this.loading = true;
listVisitor(this.queryParams).then(response => {
this.visitorList = response.rows;
this.total = response.total;
this.loading = false;
});
},
/** 查询选项列表 */
getOptions() {
this.branchOptions = []
branchTreeSelect().then(response => {
this.branchOptions = response.data
})
},
departTreeSelected(e){
this.form.deptId = e.id;
this.getPeople();
},
/** 查询选项列表 */
getPeople() {
this.queryParams1.branchId=this.form.deptId;
this.peopleOptions = []
listSysPeople(this.queryParams1).then(response => {
this.peopleOptions = response.rows
})
},
phoneToPerson(phone){
queryPeopleName({phone}).then(res => {
if(res.data){
this.form.userId = res.data.id;
this.form.userName = res.data.name;
this.form.peopleName = res.data.name;
}else{
this.$modal.msgError('为搜索到相关人员,请输入正确手机号');
}
/* let arr = [];
arr.push(res.data);
this.peopleOptions = arr; */
})
},
dataFilter(val){
let reg = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/;
if(reg.test(val)){
setTimeout(() => {
this.phoneToPerson(val)
},80)
}
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
id: null,
name: null,
phone: null,
sex: null,
avatar: null,
idcard: null,
carNo: null,
userId: null,
deptId: null,
flag: null,
startTime: null,
endTime: null,
matter: null,
res: null,
guid: null,
faceGuid: null,
remark: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.itemData = [];
this.peopleOptions = [];
this.resetForm("form");
},
/** 转换树数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
}
return {
id: node.id,
label: node.label,
isDisabled: false,
children: node.children
};
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加访客信息";
let start = moment(new Date()).format('yyyy-MM-DD HH:mm:ss')
this.$set(this.form,'startTime',start)
let end = moment(new Date()).format('yyyy-MM-DD') + ' 23:59:59'
this.$set(this.form,'endTime',end)
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
this.itemData=[];
getVisitor(id).then(response => {
this.form = response.data;
this.form.deptId = this.form.deptId.toString();
this.form.userName = this.form.peopleName;
this.itemData=response.data.itemList;
// this.getPeople();
this.open = true;
this.title = "修改访客信息";
});
},
subOf(){
if(this.form.itemList.length > 0){
this.form.itemList.forEach(ele => {
if(ele.name == '' || ele.phone == ''){
this.$modal.msgError('随访人相关信息不能为空!');
this.subFlag = 0;
}
})
}else{
this.subFlag = 1;
}
},
/** 提交按钮 */
submitForm() {
this.form.itemList=this.itemData;
this.$refs["form"].validate(valid => {
if (valid) {
this.subOf();
if(this.subFlag == 1){
if (this.form.id != null) {
updateVisitor(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.cancel();
this.getList();
});
} else {
addVisitor(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.cancel();
this.getList();
});
}
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除访客信息编号为"' + ids + '"的数据项?').then(function() {
return delVisitor(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('system/visitor/export', {
...this.queryParams
}, `visitor_${new Date().getTime()}.xlsx`)
},
// 增加一行
addRow(length) {
if (this.itemData == undefined) {
this.itemData = new Array();
}
let obj = {};
obj.avatar = "";
obj.name = "";
obj.phone = "";
this.itemData.push(obj);
},
// 删除一行
deleteRow(index) {
this.itemData.splice(index, 1)
},
handleEwm(){
this.showViewer = true
},
// 关闭查看器
closeViewer() {
this.showViewer = false
}
}
};
</script>
<style scoped lang="scss">
.card_list {
display: flex;
align-items: center;
padding: 10px;
border-radius: 5px;
cursor: pointer;
margin-bottom: 10px;
}
.published-div {
position: absolute;
top: 70px;
right: 150px;
}
.el-button--mini.is-circle {
padding: 2px;
}
.el-col-8 {
height: 60px;
}
.el-select {
width: 100%;
}
.el-date-editor.el-input, .el-date-editor.el-input__inner {
width: 100%;
}
.el-table .cell .el-upload{
line-height: 80px;
width: 80px;
height: 80px;
}
.el-table .cell .el-upload-list--picture-card .el-upload-list__item {
overflow: hidden;
background-color: #fff;
border: 1px solid #c0ccda;
border-radius: 6px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 80px;
height: 80px;
margin: 0 8px 8px 0;
display: inline-block;
}
::v-deep .people_table{
.el-upload-list--picture-card .el-upload-list__item,.el-upload--picture-card{
width:100%;
height:80px;
}
.el-upload--picture-card{
line-height:90px;
}
}
</style>